第四天:Swift利用ScrollView和CollectionView联动作标签页面滚动
参考链接:https://www.jianshu.com/p/86d2ef245596
由于18号下午发烧了,19号请假一直在家吃药休息,20号和21号周末又特懒,断写了四天,惭愧惭愧。
1 import UIKit 2 3 extension UIColor { 4 5 convenience init(r: CGFloat, g: CGFloat, b: CGFloat) { 6 7 self.init(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: 1.0) 8 } 9 10 class func arc_random() -> UIColor { 11 12 return UIColor(r: CGFloat(arc4random_uniform(256)), g: CGFloat(arc4random_uniform(256)), b: CGFloat(arc4random_uniform(256))) 13 } 14 15 class func arc_random_light() -> UIColor { 16 17 return UIColor(r: CGFloat(arc4random_uniform(128)+128), g: CGFloat(arc4random_uniform(128)+128), b: CGFloat(arc4random_uniform(128)+128)) 18 } 19 20 class func arc_random_dark() -> UIColor { 21 22 return UIColor(r: CGFloat(arc4random_uniform(128)), g: CGFloat(arc4random_uniform(128)), b: CGFloat(arc4random_uniform(128))) 23 } 24 }
1 import UIKit 2 3 let cellId = "cellId" 4 let kChannelMargin: CGFloat = 10 5 6 class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 7 8 @IBOutlet weak var collectionView: UICollectionView! 9 @IBOutlet weak var scrollView: UIScrollView! 10 11 lazy var channels: Array<String> = ["推荐", "资讯", "重庆", "社会", "军事", "娱乐", "明星", "动漫", "音乐", "影视", "政治", "历史", "二次元", "中国足球", "科技", "NBA"] 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 // Do any additional setup after loading the view, typically from a nib. 16 17 var offsetX: CGFloat = kChannelMargin 18 19 for model in channels { 20 21 let label = UILabel() 22 23 label.text = model 24 label.font = UIFont.systemFont(ofSize: 18) 25 label.textColor = UIColor.black 26 27 label.sizeToFit() 28 label.font = UIFont.systemFont(ofSize: 14) 29 30 var frame = label.frame 31 frame.origin.x = offsetX 32 frame.size.height = 35 33 label.frame = frame 34 35 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(labelClicked(withGesture:))) 36 label.addGestureRecognizer(tapGesture) 37 label.isUserInteractionEnabled = true 38 39 self.scrollView.addSubview(label) 40 41 offsetX += label.frame.size.width + kChannelMargin 42 } 43 44 self.scrollView.contentSize = CGSize(width: offsetX, height: 35) 45 46 self.setScale(withScale: 1, forIndex: 0) 47 } 48 49 override func didReceiveMemoryWarning() { 50 super.didReceiveMemoryWarning() 51 // Dispose of any resources that can be recreated. 52 } 53 54 } 55 56 extension ViewController { 57 func numberOfSections(in collectionView: UICollectionView) -> Int { 58 return 1; 59 } 60 61 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 62 return self.channels.count 63 } 64 65 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 66 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) 67 cell.backgroundColor = UIColor.arc_random_light() 68 69 let label: UILabel = cell.viewWithTag(100) as! UILabel 70 label.text = self.channels[indexPath.item] 71 72 cell.sizeToFit() 73 74 return cell 75 } 76 77 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 78 return CGSize(width: UIScreen.main.bounds.size.width, height: self.collectionView.frame.size.height); 79 } 80 81 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { 82 return UIEdgeInsetsMake(0, 0, 0, 0) 83 } 84 85 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 86 return 0.0 87 } 88 89 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 90 return 0.0 91 } 92 93 func scrollViewDidScroll(_ scrollView: UIScrollView) { 94 let ratio: CGFloat = scrollView.contentOffset.x / scrollView.frame.size.width 95 96 let index: Int = Int(ratio) 97 98 let scale: CGFloat = ratio - CGFloat(index) 99 100 if index+1 < self.channels.count { 101 self.setScale(withScale: scale, forIndex: index+1) 102 self.setScale(withScale: 1 - scale, forIndex: index) 103 } 104 } 105 } 106 107 //extension ViewController { 108 // 109 // func channelView(_ channelView: MCChannelView, forItemAt index: Int) { 110 // 111 // let indexPath = IndexPath(item: index, section: 0) 112 // 113 // self.collectionView.delegate = nil 114 // self.collectionView.scrollToItem(at: indexPath, at: .init(rawValue: 0), animated: false) 115 // self.collectionView.delegate = self 116 // } 117 //} 118 119 extension ViewController { 120 @objc func labelClicked(withGesture gesture: UITapGestureRecognizer) { 121 122 print("click click") 123 124 // 由于点击了按钮是想让页面变化,故在此应该将点击事件抛给控制器 125 126 // 使用守护语句保证操作安全 127 // 获取点击的索引值 128 guard let view = gesture.view, 129 let index: Int = self.scrollView.subviews.index(of: view) 130 else { return } 131 132 // // 构造要滚动到的位置对应的indexPath 133 // let indexPath = IndexPath(item: index, section: 0) 134 // 135 // // 为了让点击的时候按钮能慢慢变大而不调用scrollViewDidScroll直接变大,要先不调用该方法 136 // self.collectionView.delegate = nil 137 // self.collectionView.scrollToItem(at: indexPath, at: .init(rawValue: 0), animated: false) 138 // self.collectionView.delegate = self 139 140 print("%@", gesture); 141 142 // // 点击时,让点击的放大,其他缩小 143 // UIView.animate(withDuration: 0.3) { 144 // for i in 0..<self.scrollView.subviews.count { 145 // let label = self.scrollView.subviews[i] 146 // if label == gesture.view { 147 // self.setScale(withScale: 1, forIndex: i) 148 // } else { 149 // self.setScale(withScale: 0, forIndex: i) 150 // } 151 // } 152 // } 153 // 154 // self.scrollToCenter(view) 155 } 156 157 func setScale(withScale scale: CGFloat, forIndex index: Int) { 158 159 let label = self.scrollView.subviews[index] as! UILabel 160 161 label.textColor = UIColor.init(red: scale, green: 0, blue: 0, alpha: 1) 162 163 // 根据比例设置在14-18区间的字号 164 let fontSize = 14 + (18-14) * scale 165 label.transform = CGAffineTransform(scaleX: fontSize / 14, y: fontSize / 14) 166 167 // 将label移动至中央 168 self.scrollToCenter(label) 169 } 170 171 /// 将label滑动至scrollView正中的方法 172 /// 173 /// - Parameter view: 对应的label 174 func scrollToCenter(_ view: UIView) { 175 176 var offsetX = view.center.x - self.scrollView.frame.size.width * 0.5 177 178 // 如果标签旁边没有剩余标签,则不滚动 179 if offsetX < 0 { 180 offsetX = 0 181 } 182 183 self.scrollView.setContentOffset(CGPoint(x: offsetX, y: 0), animated: true) 184 } 185 }
怎么样成为程序员,学习和实践,日积月累...