模仿网易新闻客户端的滚动菜单
模仿网易新闻客户端的滚动菜单,点击菜单的时候有放大标题的动画效果。demo地址:https://github.com/BigHub/ScrollMenuViewTest
需要用到facebook的开源动画引擎pop 实现代码:
JWSegmentMenuView.swift
1 // 2 // JWSegmentMenuView.swift 3 // ScrollMenuViewTest 4 // 5 // Created by jianwei on 15/8/11. 6 // Copyright (c) 2015年 Jianwei. All rights reserved. 7 // 8 9 import UIKit 10 11 @objc protocol JWSegmentMenuViewDelegate{ 12 optional func selectItem(index:Int); 13 } 14 15 class JWSegmentMenuView: UIScrollView { 16 //MARK: - 代理 17 weak var segmentMenuViewDelegate:JWSegmentMenuViewDelegate? 18 19 //MARK: 选中的item 20 var seletedItem:JWSegmentMenuItem?{ 21 didSet{ 22 23 var scaleAnimation = POPBasicAnimation(propertyNamed: kPOPViewScaleXY) 24 scaleAnimation.duration = 0.2 25 scaleAnimation.toValue = NSValue(CGPoint: CGPointMake(1.0, 1.0)) 26 oldValue?.pop_addAnimation(scaleAnimation, forKey: "scaleAnimation") 27 oldValue?.selected = false 28 oldValue?.showBorderLine = false 29 30 var scaleAnimation2 = POPBasicAnimation(propertyNamed: kPOPViewScaleXY) 31 scaleAnimation2.duration = 0.2 32 scaleAnimation2.toValue = NSValue(CGPoint: CGPointMake(1.3, 1.3 )) 33 seletedItem?.pop_addAnimation(scaleAnimation2, forKey: "scaleAnimation2") 34 seletedItem?.selected = true 35 seletedItem?.showBorderLine = true 36 37 let index = (self.subviews as NSArray).indexOfObject(seletedItem!) 38 let previousIndex = index-1 39 let nextIndex = index + 1 40 41 var visibleRect:CGRect? 42 if previousIndex >= 0 && nextIndex < titlesArray!.count { 43 var preItem = self.subviews[previousIndex] as! JWSegmentMenuItem 44 var nextItem = self.subviews[nextIndex] as! JWSegmentMenuItem 45 visibleRect = CGRectMake(preItem.frame.origin.x, preItem.frame.origin.y, preItem.frame.size.width + nextItem.frame.size.width + seletedItem!.frame.size.width, preItem.frame.size.height) 46 }else if previousIndex < 0 || nextIndex >= titlesArray?.count { 47 visibleRect = seletedItem!.frame 48 } 49 50 self.scrollRectToVisible(visibleRect!, animated: true) 51 } 52 } 53 54 //MARK: 菜单名称列表 55 var titlesArray:NSArray?{ 56 didSet{ 57 58 if oldValue?.count > 0 { 59 (self.subviews as NSArray).enumerateObjectsUsingBlock({ (obj:AnyObject!, index:Int, stop:UnsafeMutablePointer<ObjCBool>) -> Void in 60 (obj as! UIButton).removeFromSuperview() 61 }) 62 } 63 64 if let titles = titlesArray { 65 var x:CGFloat = 0 66 titles.enumerateObjectsUsingBlock({ (obj:AnyObject!, index:Int, stop:UnsafeMutablePointer<ObjCBool>) -> Void in 67 var button:JWSegmentMenuItem = JWSegmentMenuItem.buttonWithType(UIButtonType.Custom) as! JWSegmentMenuItem 68 button.titleLabel?.font = UIFont.boldSystemFontOfSize(16) 69 print(button.titleLabel!.frame) 70 button.titleLabel?.frame = button.bounds 71 print(button.titleLabel!.frame) 72 button.setTitle(obj as? String, forState: UIControlState.Normal) 73 button.setTitleColor(self.menuTitleColor, forState: UIControlState.Normal) 74 button.setTitleColor(self.menuTitleTintColor, forState: UIControlState.Selected) 75 button.addTarget(self, action: "selectItem:", forControlEvents: UIControlEvents.TouchUpInside) 76 var str = NSString(string: obj as! String) 77 var size = str.sizeWithAttributes([NSFontAttributeName:UIFont(name: button.titleLabel!.font.fontName, size: button.titleLabel!.font.pointSize)!]) 78 size.width += 20 79 size.height = self.frame.size.height 80 button.frame = CGRectMake(x, 0.0 as CGFloat, size.width, size.height) 81 x += size.width 82 self.addSubview(button) 83 }) 84 self.contentSize = CGSizeMake(x, self.frame.size.height) 85 } 86 } 87 } 88 89 //MARK: 菜单背景色 90 var menuBackgroundColor:UIColor = UIColor(red: 172/255.0, green: 220/255.0, blue: 30/255.0, alpha: 1) 91 { 92 didSet{ 93 self.backgroundColor = menuBackgroundColor 94 } 95 } 96 97 //MARK: 菜单名称字体颜色 98 var menuTitleColor:UIColor? 99 { 100 didSet{ 101 for item in self.subviews { 102 if item is JWSegmentMenuItem { 103 (item as! JWSegmentMenuItem).setTitleColor(menuTitleColor, forState: UIControlState.Normal) 104 } 105 } 106 } 107 } 108 109 //MARK: 菜单被选中时的名称字体颜色 110 var menuTitleTintColor:UIColor? 111 { 112 didSet{ 113 for item in self.subviews { 114 if item is JWSegmentMenuItem { 115 (item as! JWSegmentMenuItem).setTitleColor(menuTitleTintColor, forState: UIControlState.Selected) 116 } 117 } 118 119 } 120 } 121 122 //MARK: 菜单背景的下划线颜色 123 var menuBackgroundUnderlineColor:UIColor = UIColor.lightGrayColor() 124 { 125 didSet{ 126 self.setNeedsDisplay() 127 } 128 } 129 130 131 override init(frame:CGRect){ 132 super.init(frame: frame) 133 self.showsHorizontalScrollIndicator = false 134 self.showsVerticalScrollIndicator = false 135 self.backgroundColor = menuBackgroundColor 136 menuTitleTintColor = UIColor.redColor() 137 menuTitleColor = UIColor.whiteColor() 138 } 139 140 required init(coder aDecoder: NSCoder) { 141 fatalError("init(coder:) has not been implemented") 142 } 143 144 // override func drawRect(rect: CGRect) { 145 // let underLinePath = UIBezierPath() 146 // underLinePath.moveToPoint(CGPointMake(0, self.frame.size.height)) 147 // underLinePath.addLineToPoint(CGPointMake(self.frame.size.width, self.frame.size.height)) 148 // underLinePath.lineWidth = 4 149 // menuBackgroundUnderlineColor.set() 150 // underLinePath.stroke() 151 // } 152 153 //MARK: - 选中item触发的方法 154 func selectItem(item:JWSegmentMenuItem){ 155 seletedItem = item 156 segmentMenuViewDelegate?.selectItem!((self.subviews as NSArray).indexOfObject(seletedItem!)) 157 } 158 159 } 160 161 class JWSegmentMenuItem: UIButton { 162 //MARK: 是否显示菜单item的下划线 163 var showBorderLine:Bool = false { 164 didSet{ 165 self.setNeedsDisplay() 166 } 167 } 168 169 // override func drawRect(rect: CGRect) { 170 // if showBorderLine { 171 // let path = UIBezierPath(); 172 // path.moveToPoint(CGPointMake(0, self.frame.height)) 173 // path.addLineToPoint(CGPointMake(self.frame.width, self.frame.height)) 174 // path.lineWidth = 6 175 // titleColorForState(UIControlState.Selected)?.set() 176 // path.stroke() 177 // } 178 // } 179 180 }
使用:
ViewController.swift
// // ViewController.swift // ScrollMenuViewTest // // Created by jianwei on 15/8/10. // Copyright (c) 2015年 Jianwei. All rights reserved. // import UIKit class ViewController: UIViewController,JWSegmentMenuViewDelegate { @IBOutlet weak var textLabel: UILabel! var segmentView:JWSegmentMenuView? lazy var titlesArray:[String] = { return ["按钮一","按钮二","按钮","按钮四","按钮五","按钮六","按钮七","按钮八","按钮九","按钮十","按钮十一","按钮十二","按钮十三"] }() override func viewDidLoad() { super.viewDidLoad() segmentView = JWSegmentMenuView(frame: CGRectMake(0, 20, self.view.frame.size.width, 33)) segmentView?.titlesArray = titlesArray segmentView?.segmentMenuViewDelegate = self self.view.addSubview(segmentView!) } //MARK: - JWSegmentMenuViewDelegate func selectItem(index: Int) { textLabel.text = titlesArray[index] } }