美文网首页
直播项目笔记(一)

直播项目笔记(一)

作者: Closer3 | 来源:发表于2017-11-30 19:50 被阅读0次

    颜色封装 + ClOPageView + 瀑布流

    搭建主题框架

    导航栏布局

    • 改变导航栏的颜色
    // 在 AppDelegate 中
    UINavigationBar.appearance().barTintColor = .black  // tintColor 是导航栏文字的颜色
    
    • 改变状态栏的颜色
    // 苹果推荐方法 在需要设置页面 controller 中
    override var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent // 默认为白色
        }
    // or
    // 在 info.plist 中 设置
    View controller-based status bar appearance 设置为 NO // 全局
    // 在 AppDelegate 中
    UIApplication.shared.statusBarStyle = .lightContent
    // or
    
    

    设置首页 NavigationBar 注意事项

    • 如果事件监听方法为私有时 要在方法前面加 @objc 公开则不需要
    // 事件监听 --> 发送消息 --> 将方法包装SEL  --> 类方法列表 --> IMP
    

    颜色封装 :UIColor + Extension

    • 拓展方法如果有参数 采用便利构造函数
    // 自定义 RGB 颜色
    convenience init(r : CGFloat, g : CGFloat, b : CGFloat, alpha : CGFloat = 1.0) {
            self.init(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: alpha)
    } 
    // 返回一个十六进制颜色
    convenience init?(hex : String, alpha : CGFloat = 1.0) {
            
            // 0xff0000
            // 1.判断字符串的长度是否符合
            guard hex.characters.count >= 6 else {
                return nil
            }
            
            // 2.将字符串转成大写
            var tempHex = hex.uppercased()
            
            // 3.判断开头: 0x/#/##
            if tempHex.hasPrefix("0x") || tempHex.hasPrefix("##") {
                tempHex = (tempHex as NSString).substring(from: 2)
            }
            if tempHex.hasPrefix("#") {
                tempHex = (tempHex as NSString).substring(from: 1)
            }
            
            // 4.分别取出RGB
            // FF --> 255
            var range = NSRange(location: 0, length: 2)
            let rHex = (tempHex as NSString).substring(with: range)
            range.location = 2
            let gHex = (tempHex as NSString).substring(with: range)
            range.location = 4
            let bHex = (tempHex as NSString).substring(with: range)
            
            // 5.将十六进制转成数字 emoji表情
            var r : UInt32 = 0, g : UInt32 = 0, b : UInt32 = 0
            Scanner(string: rHex).scanHexInt32(&r)
            Scanner(string: gHex).scanHexInt32(&g)
            Scanner(string: bHex).scanHexInt32(&b)
            
            self.init(r : CGFloat(r), g : CGFloat(g), b : CGFloat(b))
    }
    
    • 没有参数的扩展方法 用类方法
    /// 随机颜色
    class func randomColor() -> UIColor {
            return UIColor(r: CGFloat(arc4random_uniform(256)), g: CGFloat(arc4random_uniform(256)), b: CGFloat(arc4random_uniform(256)))
    }
    

    封装 CLOPageView

    • 类似网易新闻 titleView(UIScrollView) + contentView(UICollectionView)

    • 结构视图


    • 如果类中的属性没有初始化,要在创建对象super.init()前赋值 否则会报错

    // MARK: - 定义属性
        fileprivate var titles: [String]
        fileprivate var titleStyle: CLOPageStyle
        fileprivate var childVcs: [UIViewController]
        fileprivate var parentVc: UIViewController
        
        init(frame: CGRect, titles: [String], titleStyle: CLOPageStyle, childVcs: [UIViewController], parentVc: UIViewController) {
            self.titles = titles
            self.titleStyle = titleStyle
            self.childVcs = childVcs
            self.parentVc = parentVc
            
            super.init(frame: frame)
        }
    
    • 如果一个页面有多个控件继承自UIScrollView,需要设置这些控件的scrollsToTop属性,如果都为true, 则点击状态栏都不会移动
    collectionView.scrollsToTop = false
    scrollView.scrollsToTop = false
    
    • CLOTitleView中选择添加UILabel而不是UIButton的理由:UIButton中不好设置文字的属性, 直接给UILabel中添加相应的手势

    • 方法for (i, label) in titleLabels.enumerated()可以遍历数组取出数组中的元素及其下标

    • 方法w = (titles[i] as NSString).boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: 0), options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: style.titleFont], context: nil).width可以算出给定文字的宽度

    • 设置委托协议时能不继承NSObjectProtocol就不继承,因为NSObjectProtocol里的方法一般用不到,又因为weak只能修饰类,所以委托协议只需继承自class即可

    // MARK: - 设置委托协议
    protocol CLOTitleViewDelegate: class {
        func titleView(_ titleView: CLOTitleView, didSelected currentIndex: Int)
    }
    
    weak var delegate: CLOTitleViewDelegate?
    
    • 获取RGB颜色的差值方法: 分别获取R、G、B值再相减
    class func getRGBDelta(_ firstColor : UIColor, _ seccondColor : UIColor) -> (CGFloat, CGFloat,  CGFloat) {
            let firstRGB = firstColor.getRGB()
            let secondRGB = seccondColor.getRGB()
            
            return (firstRGB.0 - secondRGB.0, firstRGB.1 - secondRGB.1, firstRGB.2 - secondRGB.2)
            
    }
        
    func getRGB() -> (CGFloat, CGFloat, CGFloat) {
            guard let cmps = cgColor.components else {
                fatalError("保证普通颜色是RGB方式传入")
            }
            
            return (cmps[0] * 255, cmps[1] * 255, cmps[2] * 255)
    }
    
    • 颜色渐变动画实现思路: 先判断当前是左移还是右移,用移动前scrollView的偏移量与移动后的偏移量比较,获得移动后下一个页面的下标,再获取当前页面移动的百分比,通过代理让titleView作出相应处理,让RGB颜色差值乘以百分比
    • 底部滚动条的动画类似,让不同滚动条宽度之间的差值乘以这个百分比

    瀑布流布局

    • 瀑布流布局实现整体思路:采用UICollectionView自定义UICollectionViewFlowLayout 主要实现下面三个方法:
    // MARK:- 准备布局
    extension HYWaterfallLayout {
        // 告诉当前 layout 需要改变
        override func prepare() {
            super.prepare()
            ...
            // Cell --> UICollectionViewLayoutAttributes
            // 设置好每个 cell 的 frame        
            ...
            
    }
    
    // MARK:- 返回准备好所有布局
    extension HYWaterfallLayout {
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            return cellAttrs
        }
    }
    
    // MARK:- 设置contentSize
    extension HYWaterfallLayout {
        override var collectionViewContentSize: CGSize {
            return CGSize(width: 0, height: totalHeights.max()! + sectionInset.bottom)
        }
    }
    
    
    • 每个cellframe 计算
    // 用一个属性保存每一行 cell 的高度
    fileprivate lazy var totalHeights : [CGFloat] = Array(repeating: self.sectionInset.top, count: self.cols)
        
    // 计算当前一排最小高度及其列数
    let minH = totalHeights.min()!
    let minIndex = totalHeights.index(of: minH)!
    
    // x 和 y 值
    let cellX : CGFloat = sectionInset.left + (minimumInteritemSpacing + cellW) * CGFloat(minIndex)
    let cellY : CGFloat = minH + minimumLineSpacing
    
    // 更新当前的最小高度
    totalHeights[minIndex] = minH + minimumLineSpacing + cellH
    

    相当于将下一个 cell 加在当前一行中cellY值最小的 cell 的下面

    相关文章

      网友评论

          本文标题:直播项目笔记(一)

          本文链接:https://www.haomeiwen.com/subject/ctdbbxtx.html