• Alert 封装自定义弹窗
  • import Foundation import UIKitclass YJAlertControllerTool { /** alterController 两个按钮 处理otherBtn事件 - parameter currentVC: 当前控制器 - parameter meg: 提示消息 - parameter cancelBtn:
    import Foundation
    import UIKit
    
    class YJAlertControllerTool {
        /**
         alterController 两个按钮 处理otherBtn事件
    
         - parameter currentVC: 当前控制器
         - parameter meg:       提示消息
         - parameter cancelBtn: 取消按钮
         - parameter otherBtn:  其他按钮
         - parameter handler:   其他按钮处理事件
         */
        static func showAlert(currentVC:UIViewController, meg:String, cancelBtn:String, otherBtn:String?, handler:((UIAlertAction) -> Void)?){
    //        guard let vc = self.getCurrentVC() else{ return }
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                let alertController = UIAlertController(title:GFB_ALTER_MSG,
                    message:meg ,
                    preferredStyle: .Alert)
                let cancelAction = UIAlertAction(title:cancelBtn, style: .Cancel, handler:nil)
    
                alertController.addAction(cancelAction)
    
                if otherBtn != nil{
                    let settingsAction = UIAlertAction(title: otherBtn, style: .Default, handler: { (action) -> Void in
                        handler?(action)
                    })
                    alertController.addAction(settingsAction)
                }
                currentVC.presentViewController(alertController, animated: true, completion: nil)
            })
        }
    
    
        /**
         alterController 一个按钮 不处理事件,简单实用
    
         - parameter currentVC: 当前控制器
         - parameter meg:       提示消息
         */
        static func showAlert(currentVC:UIViewController, cancelBtn:String, meg:String){
            showAlert(currentVC, meg: meg, cancelBtn: cancelBtn, otherBtn: nil, handler: nil)
        }
    
    
        /**
         两个按钮 都处理事件
    
         - parameter currentVC:     当前控制器
         - parameter meg:           提示消息
         - parameter cancelBtn:     取消按钮
         - parameter otherBtn:      其他按钮
         - parameter cencelHandler: 取消按钮事件回调 (不处理可不写,考虑到有些场合需要使用)
         - parameter handler:       其他按钮事件回调
         */
        static func showAlert(currentVC:UIViewController, meg:String, cancelBtn:String, otherBtn:String?,cencelHandler:((UIAlertAction) -> Void)?, handler:((UIAlertAction) -> Void)?){
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                let alertController = UIAlertController(title:GFB_ALTER_MSG,
                    message:meg ,
                    preferredStyle: .Alert)
                let cancelAction = UIAlertAction(title:cancelBtn, style: .Cancel, handler:{ (action) -> Void in
                    cencelHandler?(action)
                })
                alertController.addAction(cancelAction)
                if otherBtn != nil{
                    let settingsAction = UIAlertAction(title: otherBtn, style: .Default, handler: { (action) -> Void in
                        handler?(action)
                    })
                    alertController.addAction(settingsAction)
                }
                currentVC.presentViewController(alertController, animated: true, completion: nil)
            })
        }
    }
    展开全文
  • tableview的一个简单的封装,不用每次都实现坑爹的delegate
  • Swift基础框架的封装

    2017-04-28 16:17:04
    最近闲来无事,就自学了swift编程语言,并且根据之前OC的经验,封装Swift版本的基础框架,一些常用的的方法,常用的类库和第三方,都封装到了一起,方便以后新项目的使用,在这里,分享给大家,欢迎大家下载使用,...

           最近闲来无事,就自学了swift编程语言,并且根据之前OC的经验,封装了Swift版本的基础框架,一些常用的的方法,常用的类库和第三方,都封装到了一起,方便以后新项目的使用,在这里,分享给大家,欢迎大家下载使用,丰富功能:https://github.com/CherishSmile/ZYBase

           接下来,就先简单介绍下,现阶段本框架封装的基本内容

    一、框架代码部分

           封装的swift框架的名字是:ZYBase,主要包括BaseSet、ThirdLib、Tools三大部分(如图所示):

         

          1、BaseSet是对系统的方法进行了简单的封装处理,常用的方法都在这里,直接调用即可,其中BaseSetting是对一些常用的方法进行的简单封装,BaseUI是对常用的UI控件进行的简单封装,BaseWebView是对WKWebView进行的简单封装,具体的可以参考GitHub上的Demo

          2、ThirdLib是一些常用的第三方库,主要有Alamofire、Kingfisher、LBXScan、SnapKit、SwfityJson等

          3、Tools是对ThirdLib里的第三方进行的简单封装,以及自己平时的封装,主要就是网络请求库的封装和自定义弹出框的封装,自认为很不错的

    二、demo示例部分(具体样式见demo)

    1、badgeNumber示例


    2、自定义alert示例(有四种动画,你还可以自定义样式)


    3、扫一扫示例(有微信,QQ,支付宝三种样式,还可以自定义样式)


    4、TableView自动计算行高示例(只需来两句话,就能自动计算行高,是不是很强大,具体看demo)


    5、Alamofire和Kingfisher示例(对网络请求库的简单封装,可以把json数据直接转化为model,直接上代码)


    6、WKWebView示例(带有进度条)


    三、浏览器功能

    导航右上角的那个按钮,点击后进入浏览器,如果你不小心进去了,我是不会告诉你手指滑动导航会返回哦



    欢迎大家使用、分享、改进。

    微信扫一扫或者搜索臆涵醉关注公众号,里面有很多你想不到的资源哦


    展开全文
  • 使用UIAlertController时,每个AlertAction对应一个Block,经常写重复代码,JKAlertManager将UIAlertController分散的ActionBlcok集中到一个Blcok中。
  • swift 自定义弹窗AlertView 如果你的swift项目是4.0以下 pod ‘AEAlertView’, ‘1.0’ swift4.0以上 直接pod 本文介绍实现思路 源码链接 自定义弹窗 先看图 项目思路 ...

    iOS-Swift 自定义弹窗 AlertView

    自定义AlertView 目前以支持最新版
    项目使用VFL布局

    • 如果你的swift项目是4.0以下

    pod ‘AEAlertView’, ‘1.0’

    • 如果你的swift项目是4.0以上 5.0以下

    pod ‘AEAlertView’, ‘1.7’

    • swift5.0以上 直接pod
    • 本文介绍实现思路
    • 源码链接
      自定义弹窗

    新增了动画弹窗


    • 重新优化了baseAlert 简化了使用方法
    • base的布局方式
      在这里插入图片描述

    具体demo 在GitHub中
    _ demo 点这里

    ------以下为第二版本时的内容-------

    • **在最新版本中 新增了 仿UI的弹窗, 开放了AEBaseAlertView 如果你的需求 AEAlertView和AEUIAlertView中没有 你可以继承AEBaseAlertView 来实现属于你自己的AlertView **
      (https://img-blog.csdnimg.cn/20190709203424489.gif)
      (https://img-blog.csdnimg.cn/20190709203444778.gif)
      演示的样式 在GitHub的Demo中都有 所有的属性都有说明 希望大家可以支持一下.
      如果有 你有任何问题 或者 好的建议 欢迎联系我 - email: allen.zhang0828@gmail.com -

    *** 控件支持 设置左右 上下间距 本来想提供 类方法来一句话调用, 但是每个项目的主题色不同 所有需要你 自己设置自己的主题色***

    ------以下为第一版本时的内容-------
    当然你也可以创建一个管理类来保存全局的统一性 并且提供类方法 方便别人使用

    import UIKit
    import AEAlertView
    
    class AlertView: AEAlertView {
        
        ///MARK: 快速调用
        public class func alert(_ title: String, _ message: String, _ actions:[String], handler:((AEAlertAction)->Void)?) {
            
            let alertView = AlertView()
            alertView.title = title
            alertView.message = message
            
            let cancel = AEAlertAction(title: actions[0], style: .Cancel) { (action) in
                print("取消")
                alertView.close()
            }
            alertView.addAction(action: cancel)
            
            if actions.count > 1 {
                let def = AEAlertAction(title: actions[1], style: .Default) { (action) in
                    if handler != nil {
                        handler!(action)
                    }
                    alertView.close()
                }
                alertView.addAction(action: def)
            }
            
            alertView.show()
        }
    
        
        override init(alertViewStyle: AEAlertViewStyle, title: String?, message: String?) {
            super.init(alertViewStyle: alertViewStyle, title: title, message: message)
            
            self.buttonColor = UIColor.red
            self.cancelButtonColor = UIColor.white
            self.cancelButtonLayerBorderColor = UIColor.red
            self.cancelButtonTitleColor = UIColor.red
            self.titleTopMargin = 16
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    

    在外部调用

    AlertView.alert("提示", "是否去分享", ["取消","确认"]) { (action) in
                print("确认")
            }
    

    可以复制代码 去看看效果了

    项目思路

    定义一个View 用来展示

    代码块

    override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
        }
    

    初始设置View

    alertBackgroundView = UIView(frame: CGRect.zero)
            alertBackgroundView.translatesAutoresizingMaskIntoConstraints = false
            alertBackgroundView.backgroundColor = UIColor(white: 0.97, alpha: 1.0)
            alertBackgroundView.layer.cornerRadius = 8
            addSubview(alertBackgroundView!)
            
            titleLabel = UILabel(frame: CGRect.zero)
            titleLabel.translatesAutoresizingMaskIntoConstraints = false
            titleLabel.numberOfLines = 2
            titleLabel.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
            titleLabel.textAlignment = .center
            titleLabel.textColor = UIColor.white
            titleLabel.text = "Title Label"
            alertBackgroundView.addSubview(titleLabel)
    

    设置默认布局

    let titleLabelCons = NSLayoutConstraint.constraints(withVisualFormat: "H:|-51@750-[titleLabel]-51@750-|", options: NSLayoutFormatOptions(rawValue: 0), metrics:nil, views: ["titleLabel":titleLabel])
            alertBackgroundView.addConstraints(titleLabelCons)
    

    在暴露接口 封装动画

    UIApplication.shared.delegate?.window??.addSubview(self)
    
            alertView?.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
            alertView?.alpha = 0
            
            UIView.animate(withDuration: 0.5,
                           delay: 0,
                           usingSpringWithDamping: 0.7,
                           initialSpringVelocity: 0.5,
                           options: .curveEaseInOut,
                           animations: {
                            self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
                            self.alertView?.transform = CGAffineTransform(scaleX: 1, y: 1)
                            self.alertView?.alpha = 1
            },
                           completion: nil)
    

    你还可以自定义尺寸
    具体属性代码里都有

    ///内容高度如果文字超出 文字可以滚动 Content height can scroll if text exceeds text
        public var messageHeight: Int? {
            didSet {
                guard let height = messageHeight else { return }
                setMessageHeight(height: height)
            }
        }
        
        ///添加action AddAction
        public func addAction(action: AEAlertAction) {
            actions?.append(action)
        }
    
        ///alert背景色 The background color of the alert view
        public var alertViewBackgroundColor: UIColor? {
            didSet {
                setAlertViewBackgroundColor(color: alertViewBackgroundColor!)
            }
        }
    
        ///Title字体 The font used to display the title in the alert view
        public var titleFont: UIFont! {
            didSet {
                setTitleFont(font: titleFont)
            }
        }
    
        ///message字体 The font used to display the messsage in the alert view
        public var messageFont: UIFont! {
            didSet {
                setMessageFont(font: messageFont)
            }
        }
    

    最后在次附上链接 感谢您的Star
    AEAlertView链接求Star

    展开全文
  • swift UIAlertController 添加tableview 有例子可以学习下吗
  • UIAlertView 和 UIActionSheet,对于我们来说,一点也不陌生。但是在iOS8 以后,推出UIAlertController后,UIAlertViewh和UIActionSheet就被废弃了。而对于使用的已经很习惯的UIAlertView、UIActionSheet的书写方式来...

    UIAlertView 和 UIActionSheet,对于我们来说,一点也不陌生。但是在iOS8 以后,推出UIAlertController后,UIAlertViewh和UIActionSheet就被废弃了。而对于使用的已经很习惯的UIAlertView、UIActionSheet的书写方式来说,UIAlertController的写法,简直麻烦到令人发指。起码我个人是这么觉得的。在此基础上,我在此前的项目中,使用Objective-C封装了一套类似于UIAlertView、UIActionSheet写法的UIAlertController, 使用起来,效果还可以。因为现在用Swift开发,所以将之前的Objective-C版本,翻译成Swift版本。 仅供参考

    //
    //  CustomAlertController.swift
    //  AlertController
    //
    //  Created by YLJ on 2017/6/19.
    //  Copyright © 2017年 YLJ. All rights reserved.
    //
    
    import UIKit
    
    // 弹出框样式
    enum UIAlertStyle: Int {
        case actionSheet = 0
        case alert = 1
    }
    
    class CustomAlertController: NSObject {
        
        // MARK: 私有变量
        // 系统弹出框样式
        private var alertControllerStyle: UIAlertControllerStyle!
        // action 样式
        private var alertActionStyle: UIAlertActionStyle!
        private var alertController: UIAlertController!
        // 标题
        private var ljtitle: String!
        // 消息
        private var ljmessage: String!
    
        // MARK: 公有属性
        var titleColor: UIColor = UIColor.black {
            didSet {
                if ljtitle != nil && ljtitle.characters.count > 0 {
                    changeTitle()
                }
            }
        }
        var messageColor: UIColor = UIColor.black {
            didSet {
                if ljmessage != nil && ljmessage.characters.count > 0 {
                    changeMessage()
                }
            }
        }
        var cancelTitleColor: UIColor = UIColor.black {
            didSet {
                let acrion = alertController.actions.first
                acrion?.setValue(cancelTitleColor, forKey: "titleTextColor")
            }
        }
        var otherTitlesColor: UIColor = UIColor.black {
            didSet {
                for (index, value) in alertController.actions.enumerated() {
                    if index != 0 {
                        let action = value
                        action.setValue(otherTitlesColor, forKey: "titleTextColor")
                    }
                }
            }
        }
        var titleFont: UIFont = UIFont.systemFont(ofSize: 17) {
            didSet {
                if ljtitle != nil && ljtitle.characters.count > 0 {
                    changeTitle()
                }
            }
        }
        var messageFont: UIFont = UIFont.systemFont(ofSize: 13) {
            didSet {
                if ljmessage != nil && ljmessage.characters.count > 0 {
                    changeMessage()
                }
            }
        }
    
        // MARK: 初始化方法
        init(vc: UIViewController?=nil, title: String?=nil, message: String?=nil,
             cancelTitle: String?=nil, otherTitles: [String]?=nil, style: UIAlertStyle,
             closure: @escaping ((_ action: UIAlertAction, _ index: Int) -> ())) {
            super.init()
            
            switch style {
            case .actionSheet:
                alertControllerStyle = .actionSheet
                break
            case .alert:
                alertControllerStyle = .alert
                break
            }
            
            // 临时标题,为了防止title与message同时为nil,导致程序崩溃
            var tempTitle = title
            if title == nil && message == nil {
                tempTitle = ""
            }
            alertController = UIAlertController.init(title: tempTitle, message: message, preferredStyle: alertControllerStyle)
    
            var titles: [String] = []
            if cancelTitle != nil {
                titles.insert(cancelTitle!, at: 0)
            }
            
            if otherTitles != nil {
                titles = titles+otherTitles!
            }
            
            for (ind, value) in titles.enumerated() {
                if (cancelTitle != nil) && (ind == 0) {
                    alertActionStyle = .cancel
                } else {
                    alertActionStyle = .default
                }
                
                let customAction = UIAlertAction.init(title: value, style: alertActionStyle, handler: {(action) in
                    closure(action, ind)
                })
                
                if title != nil {
                    ljtitle = title!
                    changeTitle()
                }
                
                if message != nil {
                    ljmessage = message
                    changeMessage()
                }
                
                if alertActionStyle == .cancel {
                    customAction.setValue(cancelTitleColor, forKey: "titleTextColor")
                } else {
                    customAction.setValue(otherTitlesColor, forKey: "titleTextColor")
                }
                alertController.addAction(customAction)
            }
            
            if vc != nil {
                vc?.present(alertController, animated: true, completion: nil)
            } else {
                UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
            }
        }
        
        // 改变标题
        private func changeTitle() {
            changeText(text: ljtitle, attribute1: NSForegroundColorAttributeName,
                       value1: titleColor, attribute2: NSFontAttributeName,
                       value2: titleFont, range: NSRange(location: 0, length: ljtitle.characters.count),
                       key: "attributedTitle")
        }
        // 改变消息
        private func changeMessage() {
            changeText(text: ljmessage, attribute1: NSForegroundColorAttributeName,
                       value1: messageColor, attribute2: NSFontAttributeName,
                       value2: messageFont, range: NSRange(location: 0, length: ljmessage.characters.count),
                       key: "attributedMessage")
        }
        // 改变文字
        private func changeText(text: String, attribute1: String, value1: Any,
                                attribute2: String, value2: Any, range: NSRange, key: String) {
            let alertControllerStr = NSMutableAttributedString.init(string: text)
            alertControllerStr.addAttributes([attribute1: value1], range: range)
            alertControllerStr.addAttributes([attribute2: value2], range: range)
            alertController.setValue(alertControllerStr, forKey: key)
        }
    }
    


    展开全文
  • UITableView功能强大,但是使用delegate设计模式的DataSource真的很不舒服。比如说: 一堆冗长的函数签名 只能拷贝,错一点都无法执行的,也不会提示你不对 冗长的函数签名是这样的: func numberOfSections(in: ...

    UITableView功能强大,但是使用delegate设计模式的DataSource真的很不舒服。比如说:

    1. 一堆冗长的函数签名
    2. 只能拷贝,错一点都无法执行的,也不会提示你不对

    冗长的函数签名是这样的:

    func numberOfSections(in: UITableView) -> Int 
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 复制代码

    是否可以给它一个DataSource对象,它自己就可以显示内容即可呢,就像这样:

    tableview.Datasource = [["java","swift","js"],["java","swift","js"]]

    它应该可以

    1. 自己提取发现有两个section
    2. 每个section内的row的数量
    3. 以及要显示到Cell的内容。

    这是可能的,实际上,如下类Table封装完毕,使用的时候,就是可以达成希望的效果的,使用Table,你不必在自己编写这些函数,代码如下:

    import UIKit
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            self.window = UIWindow(frame: UIScreen.main.bounds)
            let page = Page()
            page.view.backgroundColor = .blue
            self.window!.rootViewController = page
            self.window?.makeKeyAndVisible()
            return true
        }
    }
    class Page: UIViewController {
        var a : Table!
        override func viewDidLoad() {
            super.viewDidLoad()
            a  = Table()
            a.ds = [["java","swift","js"],["java","swift","js"]]
            a.frame = CGRect(x: 0,y: 50,width: 300,height: 500)
            self.view.addSubview(a)
        }
    }
    class Table : UITableView,UITableViewDataSource,UITableViewDelegate{
        public var  ds : [[Any]]
        override init(frame: CGRect, style: UITableViewStyle) {
            ds = []
            super.init(frame:frame,style:style)
    
            self.dataSource = self
            self.delegate = self
        }
        required init?(coder aDecoder: NSCoder) {
            ds = []
            super.init(coder:aDecoder)
        }
        func numberOfSections(in: UITableView) -> Int {
            return ds.count
        }
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 44
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return ds[section].count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let arr = ds
            let a = UITableViewCell(style: .default, reuseIdentifier: nil)
            a.textLabel?.text = String(describing:arr[indexPath.section][indexPath.row])
            return a
        }
    }复制代码

    这个案例有很多限制,比如数据源内的数据项,只能是String类型。如果想要一般的对象作为数据项,更加花哨的Cell作为外观,有办法吗?关键就是,让Cell的类型是参数化的,可以传递和修改的。为此,我们需要在Table内加入一个cellClass的类,它可以由使用这套封装的开发者传递进来。如下案例,已经完成了此工作,并提供了对象化的数据项作为案例:

     import UIKit
     @UIApplicationMain
     class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            self.window = UIWindow(frame: UIScreen.main.bounds)
            let page = Page()
            page.view.backgroundColor = .blue
            self.window!.rootViewController = page
            self.window?.makeKeyAndVisible()
            return true
        }
     }
     class Page: UIViewController {
        var a : Table!
        override func viewDidLoad() {
            super.viewDidLoad()
            var s = DoubleString("Paris","Charles de Gaulle")
            var t = DoubleString("Rome","FCO")
            a  = Table()
            a.cellClass = DoubleStringCell.self
            a.ds = [[s,t]]
            a.load()
            a.frame = CGRect(x: 0,y: 50,width: 300,height: 500)
            self.view.addSubview(a)
        }
     }
     class DoubleString{
        var s1 : String
        var s2 : String
        init(_ s1:String,_ s2:String){
            self.s1=s1
            self.s2=s2
        }
     }
     class DoubleStringCell:Cell{
        var l1 : UILabel?=UILabel()
        var l2 : UILabel?=UILabel()
        override func layoutSubviews() {
            l1?.frame = CGRect(x: 0, y: 0,width: 200,height: 20)
            self.addSubview(l1!)
            l2?.frame = CGRect(x: 0, y: 25,width: 200,height: 20)
            self.addSubview(l2!)
        }
        override  func loadData(_ obj : Any){
            let ds = obj as! DoubleString
            l1?.text = ds.s1
            l2?.text = ds.s2
        }
     }
     class StringCell:Cell{
        override  func loadData(_ obj : Any){
            textLabel?.text = "\(obj)"
        }
     }
     // Framework Zone
     class Table: UITableView,UITableViewDataSource,UITableViewDelegate{
        var ds_ : [[Any]]?
        public var  ds : [[Any]]?{
            get{return ds_}
            set{
                ds_ = newValue
            }
        }
        var  cellClass_ : AnyClass?
        public var  cellClass : AnyClass?{
            get{return cellClass_}
            set{cellClass_ = newValue}
        }
        func load(){
            self.dataSource = self
            self.delegate = self
            register( cellClass, forCellReuseIdentifier: "\(cellClass)");
            print("\(cellClass)")
        }
        func numberOfSections(in: UITableView) -> Int {
            return ds!.count
        }
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 44
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return ds![section].count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let arr = ds!
            let a  = dequeueReusableCell(withIdentifier: "\(cellClass)", for: indexPath) ;
            loadCell(a,arr[indexPath.section][indexPath.row])
            return a
        }
        func loadCell(_ cell : UITableViewCell,_ item : Any){
            (cell as! Cell).loadData(item)
        }
    }
    
     class Cell : UITableViewCell{
        public func loadData(_ obj : Any){
            textLabel?.text = "implements yourself cell for \(obj)"
        }
     }复制代码

    继承了Cell,并且实现了loadData,就可以在loadData内自己加载任何传入进来的数据项对象,这里的数据项对象是DoubleString,内部承载了两个字符串。当然还可以是任何类型的对象,反正在自己的loadData内自己编写加载数据项对象就可以了。

    当然,这段代码依然并不理想,因为loadData的实现,依然要求开发者自己覆盖基础类Cell的loadData。这样的耦合并不讨喜。最好是此处的函数也可以参数化,方法就是让开发者自己传递一个事件函数进来,需要时,框架调用用户的事件函数:

    import UIKit
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            self.window = UIWindow(frame: UIScreen.main.bounds)
            let page = Page()
            page.view.backgroundColor = .blue
            self.window!.rootViewController = page
            self.window?.makeKeyAndVisible()
            return true
        }
    }
    class Page: UIViewController {
        var a : Table!
        override func viewDidLoad() {
            super.viewDidLoad()
            var s = DoubleString("Paris","Charles de Gaulle")
            var t = DoubleString("Rome","FCO")
            a  = Table()
            a.onCellData = {(cell ,obj) in
                let ds = obj as! DoubleString
                let c = cell as! DoubleStringCell
                c.l1?.text = ds.s1
                c.l2?.text = ds.s2
            }
            a.cellClass = DoubleStringCell.self
            a.ds = [[s,t]]
            a.load()
            a.frame = CGRect(x: 0,y: 50,width: 300,height: 500)
            self.view.addSubview(a)
        }
    }
    class DoubleString{
        var s1 : String
        var s2 : String
        init(_ s1:String,_ s2:String){
            self.s1=s1
            self.s2=s2
        }
    }
    class DoubleStringCell:UITableViewCell{
        var l1 : UILabel?=UILabel()
        var l2 : UILabel?=UILabel()
        override func layoutSubviews() {
            l1?.frame = CGRect(x: 0, y: 0,width: 200,height: 20)
            self.addSubview(l1!)
            l2?.frame = CGRect(x: 0, y: 25,width: 200,height: 20)
            self.addSubview(l2!)
        }
    }
    // Framework Zone
    typealias  OnCellData = (_ cell : UITableViewCell ,_ obj : Any)->Void
    class Table: UITableView,UITableViewDataSource,UITableViewDelegate{
        var ds_ : [[Any]]?
        var onCellData_ : OnCellData?
        var onCellData : OnCellData?{
            get{return onCellData_}
            set{
                onCellData_ = newValue
            }
        }
        public var  ds : [[Any]]?{
            get{return ds_}
            set{
                ds_ = newValue
            }
        }
        var  cellClass_ : AnyClass?
        public var  cellClass : AnyClass?{
            get{return cellClass_}
            set{cellClass_ = newValue}
        }
        func load(){
            self.dataSource = self
            self.delegate = self
            register( cellClass, forCellReuseIdentifier: "\(cellClass)");
            print("\(cellClass)")
        }
        func numberOfSections(in: UITableView) -> Int {
            return ds!.count
        }
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 44
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return ds![section].count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let arr = ds!
            let a  = dequeueReusableCell(withIdentifier: "\(cellClass)", for: indexPath) ;
            loadCell(a,arr[indexPath.section][indexPath.row])
            return a
        }
        func loadCell(_ cell : UITableViewCell,_ item : Any){
            onCellData_?(cell,item)
        }
    }复制代码

    原本需要继承并覆盖的loadData现在可以转移为事件,从而砍掉一些不自在的代码。此案例中,还有一处可以稍微优化,就是viewDidLoad内的DoubleString,喜爱Swift的字面量对象的话,可以改写为数组,反正解析的时候,转换为数组就好:

    override func viewDidLoad() {
        super.viewDidLoad()        
        a  = Table()
        a.onCellData = {(cell ,obj) in
            let ds = obj as! [String]
            let c = cell as! DoubleStringCell
            c.l1?.text = ds[0]
            c.l2?.text = ds[1]
        }
        a.cellClass = DoubleStringCell.self
        a.ds = [[["Paris","Charles de Gaulle"],["Rome","FCO"]]]
        a.load()
        a.frame = CGRect(x: 0,y: 50,width: 300,height: 500)
        self.view.addSubview(a)
    }复制代码
    展开全文
  • 目前为止,最为精简的 alert 和 actionSheet 封装!DSAlert 让你的弹框不再孤单! 功能: 可以自定义每个按钮的字体颜色了! 再次设计结构,新增frameWork静态库文件封装,喜欢简洁的你可以直接导入frameWork即可! ...
  • func alertSheet(_ title: String?, _ message: String?, list: [String], result: @escaping ((_ index: Int) -> ())) { let current = UIViewController.current() let alert = UIAlert...
  • let alert = UIAlertController(title: "alertView", message: "clickedButton event", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "cancel", style: UIAlertAct
  • 对于应用来说,每个用户都有自己的独特偏好设置,而好的应用会让用户根据喜好选择合适的使用方式,把这些偏好记录在应用包的plist文件中,通过NSUserDefaults类来访问,这是NSUserDefaults的常用姿势。...
  • 重新封装更灵活的AlertView、DatePickerView、PickerView、SheetView
  • 最近要做一个iOS相机及相册图片上传,其中遇到了这些问题:1、图片增删在UICollectionView里的变化;2、获取相机拍摄的照片和相册的照片;3、将PHAsset对象转为UIImage对象; 具体实现过程: ...
  • swift简单学习之封装

    2016-04-08 23:22:22
    在一年的OC开发过程中,终于有点封装的思想了。看到最近swift火的一塌糊涂 就没事研究一下。看了几篇开源项目,慢慢的似乎摸通了一些门道。在面向对象语言中封装这个东西。又不得不重新 理解。 在view中要对width...
  • 最近需要使用到提示框(警告框)进行信息的展示和提醒,所以进行了一个类的封装,想用Swift调用此OC文件,但是发现有些困难,所以暂时先把OC代码进行展示,随后再好好研究一下在Swift中的使用。对于封装文件,首先要...
  • Swift编程的15个技巧

    2019-07-05 10:06:53
    自2014年9月1.0版发布后,Savvy的应用开发团队就开始在iOS项目中实验并使用Swift。不过由于Swift相对还很新,当时大多项目仍在使用Objective-C;自从2015年9月Swift 2.0版本发布以来,我们已经开始改用Swift来编译新...
  • 好的团队离不开大家的默契合作,在开发中经常遇到H5和移动端合作的业务,在开发中JS交互是非常常见的,小萌现在的主打语言是Swift,所以封装一下Swift版的JS交互
1 2 3 4 5 ... 20
收藏数 779
精华内容 311