参考链接:https://github.com/soapyigu/Swift-30-Projects

 

1 import UIKit
2 
3 struct Work {
4     let title: String
5     let image: UIImage
6     let info: String
7     var isExpanded: Bool
8 }

 

 1 import UIKit
 2 
 3 struct Artist {
 4     let name: String
 5     let bio: String
 6     let image: UIImage
 7     var works: [Work]
 8     
 9     init(name: String, bio: String, image: UIImage, works: [Work]) {
10         self.name = name
11         self.bio = bio
12         self.image = image
13         self.works = works
14     }
15     
16     static func artistsFromBundle() -> [Artist] {
17         
18         var artists = [Artist]()
19         
20         guard let url = Bundle.main.url(forResource: "artists", withExtension: "json") else {
21             return artists
22         }
23         
24         do {
25             let data = try Data.init(contentsOf: url)
26             guard let rootObject = try
27                 JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else {
28                     return artists
29             }
30             
31             guard let artistObjects = rootObject["artists"] as? [[String: AnyObject]] else {
32                 return artists
33             }
34             
35             for artistObject in artistObjects {
36                 if let name = artistObject["name"] as? String,
37                     let bio = artistObject["bio"] as? String,
38                     let imageName = artistObject["image"] as? String,
39                     let image = UIImage.init(named: imageName),
40                     let worksObject = artistObject["works"] as? [[String : String]] {
41                     
42                     var works = [Work]()
43                     
44                     for workObject in worksObject {
45                         if let workTitle = workObject["title"],
46                             let workImageName = workObject["image"],
47                             let workImage = UIImage.init(named: workImageName + ".jpg"),
48                             let info = workObject["info"] {
49                             
50                             works.append(Work(title: workTitle, image: workImage, info: info, isExpanded: false))
51                         }
52                     }
53                     
54                     let artist = Artist(name: name, bio: bio, image: image, works: works)
55                     artists.append(artist)
56                 }
57             }
58         } catch {
59             return artists
60         }
61         
62         return artists
63     }
64 }

 

 1 import UIKit
 2 
 3 class ArtistTableViewCell: UITableViewCell {
 4     
 5     @IBOutlet weak var bioLabel: UILabel!
 6     @IBOutlet weak var nameLabel: UILabel!
 7     @IBOutlet weak var artistImageView: UIImageView!
 8 
 9     override func awakeFromNib() {
10         super.awakeFromNib()
11         // Initialization code
12     }
13 
14     override func setSelected(_ selected: Bool, animated: Bool) {
15         super.setSelected(selected, animated: animated)
16 
17         // Configure the view for the selected state
18     }
19 
20 }

 

 1 import UIKit
 2 
 3 class WorkTableViewCell: UITableViewCell {
 4 
 5     @IBOutlet weak var workImageView: UIImageView!
 6     @IBOutlet weak var workTitleLabel: UILabel!
 7     @IBOutlet weak var moreInfoTextView: UITextView!
 8     
 9     override func awakeFromNib() {
10         super.awakeFromNib()
11         // Initialization code
12     }
13 
14     override func setSelected(_ selected: Bool, animated: Bool) {
15         super.setSelected(selected, animated: animated)
16 
17         // Configure the view for the selected state
18     }
19 
20 }

 

 1 import UIKit
 2 
 3 class ArtistListViewController: UIViewController {
 4 
 5     let artists = Artist.artistsFromBundle()
 6     
 7     @IBOutlet weak var tableView: UITableView!
 8     
 9     override func viewDidLoad() {
10         super.viewDidLoad()
11 
12         // Do any additional setup after loading the view.
13         
14         tableView.rowHeight = UITableViewAutomaticDimension
15         tableView.estimatedRowHeight = 140
16         
17         NotificationCenter.default.addObserver(forName: .UIContentSizeCategoryDidChange, object: .none, queue: OperationQueue.main) { [weak self] _ in
18             self?.tableView.reloadData()
19         }
20     }
21 
22     override func didReceiveMemoryWarning() {
23         super.didReceiveMemoryWarning()
24         // Dispose of any resources that can be recreated.
25     }
26     
27     // MARK: - Navigation
28 
29     // In a storyboard-based application, you will often want to do a little preparation before navigation
30     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
31         // Get the new view controller using segue.destinationViewController.
32         // Pass the selected object to the new view controller.
33         if let destination = segue.destination as? ArtistDetailViewController,
34             let indexPath = tableView.indexPathForSelectedRow {
35             destination.selectedArtist = artists[indexPath.row]
36         }
37     }
38 
39 }
40 
41 extension ArtistListViewController: UITableViewDataSource {
42     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
43         return artists.count
44     }
45     
46     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
47         let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ArtistTableViewCell
48         
49         let artist = artists[indexPath.row]
50         
51         cell.bioLabel.text = artist.bio
52         cell.bioLabel.textColor = UIColor.init(white: 114 / 255, alpha: 1)
53         
54         cell.artistImageView.image = artist.image
55         cell.nameLabel.text = artist.name
56         
57         cell.nameLabel.backgroundColor = UIColor.init(red: 1, green: 152 / 255, blue: 0, alpha: 1)
58         cell.nameLabel.textColor = UIColor.white
59         cell.nameLabel.textAlignment = .center
60         cell.selectionStyle = .none
61         
62         cell.nameLabel.font = UIFont.preferredFont(forTextStyle: .headline)
63         cell.bioLabel.font = UIFont.preferredFont(forTextStyle: .body)
64         
65         return cell
66     }
67 }

 

 1 import UIKit
 2 
 3 class ArtistDetailViewController: UIViewController {
 4 
 5     var selectedArtist: Artist!
 6     
 7     let moreInfoText = "Select For More info >"
 8     
 9     @IBOutlet weak var tableView: UITableView!
10     
11     override func viewDidLoad() {
12         super.viewDidLoad()
13 
14         // Do any additional setup after loading the view.
15         
16         title = selectedArtist.name
17         
18         tableView.rowHeight = UITableViewAutomaticDimension
19         tableView.estimatedRowHeight = 300
20         
21         NotificationCenter.default.addObserver(forName: .UIContentSizeCategoryDidChange, object: .none, queue: OperationQueue.main) { [weak self] _ in
22             self?.tableView.reloadData()
23         }
24     }
25 
26     override func didReceiveMemoryWarning() {
27         super.didReceiveMemoryWarning()
28         // Dispose of any resources that can be recreated.
29     }
30     
31 
32     /*
33     // MARK: - Navigation
34 
35     // In a storyboard-based application, you will often want to do a little preparation before navigation
36     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
37         // Get the new view controller using segue.destinationViewController.
38         // Pass the selected object to the new view controller.
39     }
40     */
41 
42 }
43 
44 extension ArtistDetailViewController: UITableViewDataSource {
45     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
46         return selectedArtist.works.count
47     }
48     
49     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
50         let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! WorkTableViewCell
51         
52         let work = selectedArtist.works[indexPath.row]
53         
54         cell.workTitleLabel.text = work.title
55         cell.workImageView.image = work.image
56         
57         cell.workTitleLabel.backgroundColor = UIColor.init(white: 204 / 255, alpha: 1)
58         cell.workTitleLabel.textAlignment = .center
59         cell.moreInfoTextView.textColor = UIColor.init(white: 114 / 255, alpha: 1)
60         cell.selectionStyle = .none
61         
62         cell.moreInfoTextView.text = work.isExpanded ? work.info : moreInfoText
63         cell.moreInfoTextView.textAlignment = work.isExpanded ? .left : .center
64         
65         cell.workTitleLabel.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
66         cell.moreInfoTextView.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.footnote)
67         
68         return cell
69     }
70 }
71 
72 extension ArtistDetailViewController: UITableViewDelegate {
73     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
74         guard let cell =  tableView.cellForRow(at: indexPath) as? WorkTableViewCell else {
75             return
76         }
77         
78         var work = selectedArtist.works[indexPath.row]
79         
80         work.isExpanded = !work.isExpanded
81         selectedArtist.works[indexPath.row] = work
82         
83         cell.moreInfoTextView.text = work.isExpanded ? work.info : moreInfoText
84         cell.moreInfoTextView.textAlignment = work.isExpanded ? .left : .center
85         
86         tableView.beginUpdates()
87         tableView.endUpdates()
88         
89         tableView.scrollToRow(at: indexPath, at: .top, animated: true)
90         
91     }
92 }

 

转载于:https://www.cnblogs.com/chmhml/p/8484679.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐