swift侧栏框点击事件_axure 点击元件时隐藏侧栏,再次点击时出现侧栏 - CSDN
  • [Swift]左右侧边栏

    2018-07-30 17:41:37
    DEMO:... 应用入口(AppDelegate.swift) import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? ...

    DEMO:http://download.csdn.net/detail/u012881779/9226539

    应用入口(AppDelegate.swift

    
    import UIKit
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            
            window = UIWindow(frame: UIScreen.mainScreen().bounds)
            window?.backgroundColor = UIColor.whiteColor()
            
            let sidebar = DMSidebarViewController()
            let nav = UINavigationController(rootViewController: sidebar)
            nav.navigationBarHidden = true
            window?.rootViewController = nav
            
            window?.makeKeyAndVisible()
            
            return true
        }
    
        func applicationWillResignActive(application: UIApplication) {
       }
    }
    
    

    侧栏管理(DMSidebarViewController.swift)

    
    import UIKit
    
    class DMSidebarViewController: UIViewController {
        let LeftWidthFloat  : CGFloat = 150.0;
        let RightWidthFloat : CGFloat = 200.0;
        let screenRect = UIScreen.mainScreen().bounds
    
        var leftVC  = DMLeftViewController()
        var homeVC  = DMHomeViewController()
        var rightVC = DMRightViewController()
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let screenRect = UIScreen.mainScreen().bounds
            leftVC.view.frame = CGRectMake(-screenRect.size.width, 0, screenRect.size.width, screenRect.size.height)
            leftVC.sidebarVC = self
            self.view.addSubview(leftVC.view)
            
            homeVC.view.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height)
            homeVC.sidebarVC = self
            self.view.addSubview(homeVC.view)
            
            rightVC.view.frame = CGRectMake(screenRect.size.width, 0, screenRect.size.width, screenRect.size.height)
            rightVC.sidebarVC = self
            self.view.addSubview(rightVC.view)
            
        }
        
        //弹出左侧栏
        func popUpLeftAction(){
            UIView.animateWithDuration(0.3, animations: {
                self.leftVC.view.frame = CGRectMake(-self.screenRect.size.width + self.LeftWidthFloat, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.leftVC.view)
                
                self.homeVC.view.frame = CGRectMake(0 + self.LeftWidthFloat, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.homeVC.view)
                
                self.rightVC.view.frame = CGRectMake(self.screenRect.size.width + self.LeftWidthFloat, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.rightVC.view)
                
                }, completion:{(finished : Bool) -> Void in
            
            })
        }
        
        //页面归原位
        func popUpHomeAction(){
            UIView.animateWithDuration(0.3, animations: {
                self.leftVC.view.frame = CGRectMake(-self.screenRect.size.width, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.leftVC.view)
                
                self.homeVC.view.frame = CGRectMake(0, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.homeVC.view)
                
                self.rightVC.view.frame = CGRectMake(self.screenRect.size.width, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.rightVC.view)
                
                }, completion:{(finished : Bool) -> Void in
                    
            })
        }
        
        //弹出右侧栏
        func popUpRightAction(){
            UIView.animateWithDuration(0.3, animations: {
                self.leftVC.view.frame = CGRectMake(-self.screenRect.size.width - self.RightWidthFloat, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.leftVC.view)
                
                self.homeVC.view.frame = CGRectMake(0 - self.RightWidthFloat, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.homeVC.view)
                
                self.rightVC.view.frame = CGRectMake(self.screenRect.size.width - self.RightWidthFloat, 0, self.screenRect.size.width, self.screenRect.size.height)
                self.view.addSubview(self.rightVC.view)
                
                }, completion:{(finished : Bool) -> Void in
                    
            })
        }
    }
     

    首页(DMHomeViewController.swift)

    
    import UIKit
    
    class DMHomeViewController: DMBaseViewController {
        var sidebarVC : DMSidebarViewController!
        var leftPanGesture = UISwipeGestureRecognizer()
        var rightPanGesture = UISwipeGestureRecognizer()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            //向左方向滑动
            leftPanGesture.direction = UISwipeGestureRecognizerDirection.Left
            leftPanGesture.addTarget(self, action: "tapRightSideAction:")
            self.view.addGestureRecognizer(leftPanGesture)
            
            //向右方向滑动
            rightPanGesture.direction = UISwipeGestureRecognizerDirection.Right
            rightPanGesture.addTarget(self, action: "tapLeftSideAction:")
            self.view.addGestureRecognizer(rightPanGesture)
        }
    
        //点击按钮弹出左边栏
        @IBAction func tapLeftSideAction(sender: AnyObject) {
            if(self.view.frame.origin.x == 0){
                sidebarVC.popUpLeftAction()
            }else{
                sidebarVC.popUpHomeAction()
            }
        }
       
        //点击按钮弹出右边栏
        @IBAction func tapRightSideAction(sender: AnyObject) {
            if(self.view.frame.origin.x == 0){
                sidebarVC.popUpRightAction()
            }else{
                sidebarVC.popUpHomeAction()
            }
        }
    }
     

     

     

    示意图:

     

    展开全文
  • 包括官方在内,资料都是使用oc来完成效果的实现,自己就使用Swift纯代码来构建,以后也可以慢慢使用到较大项目中。对于这个导航的实现,已经有了非常优秀的第三方库来供我们使用:John-Llunch的...

    这篇文章使用快速的、方便的的实现方法来构建和facebook一样的”滑出式导航”。 包括官方在内,资料都是使用oc来完成效果的实现,自己就使用Swift纯代码来构建,以后也可以慢慢使用到较大项目中。

    对于这个导航的实现,已经有了非常优秀的第三方库来供我们使用:John-Llunch的SWRevealViewController 和Mutual Mobile的MMDrawerController,这里我使用的是MMDrawerController,有兴趣的可以使用SWRevealViewControler来实现一遍。

    开始实战:

    第一步:使用Cocoapods导入框架

      pod 'MMDrawerController', '~> 0.5.7'
    

    第二步:初始化根试图、左视图和中心视图(这里只做了左视图,右视图类似)

      var window: UIWindow?
    

        var drawerController:MMDrawerController!
        
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

            //创建窗口
            let mainFrame = UIScreen.mainScreen().bounds
            window = UIWindow(frame: mainFrame)
            //设置视图
            let leftViewController = LeftViewController()
            let centerViewController = CenterViewController()
            
            let centerNavigationController = UINavigationController(rootViewController: centerViewController)
            //let leftNavigationController = UINavigationController(rootViewController: leftViewController)
            
            drawerController = MMDrawerController(centerViewController: centerNavigationController, leftDrawerViewController: leftViewController)
            
            drawerController.maximumLeftDrawerWidth = Common.screenWidth * 0.70
            //手势
            drawerController.openDrawerGestureModeMask = MMOpenDrawerGestureMode.All
            drawerController.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.All
            
            //设置动画,这里是设置打开侧栏透明度从0到1
            drawerController.setDrawerVisualStateBlock { (drawerController, drawerSide, percentVisible) -> Void in
                
                var sideDrawerViewController:UIViewController?
                if(drawerSide == MMDrawerSide.Left){
                    sideDrawerViewController = drawerController.leftDrawerViewController;
                }
                sideDrawerViewController?.view.alpha = percentVisible
            }
            //设置根试图
            self.window?.rootViewController = drawerController
            //设置可见
            window?.makeKeyAndVisible()
            return true
        }

    针对第二步,基本属性和方法的使用请参考Github的文档介绍,可以参考oc的讲解和这里的Swift代码来理解。

    第三步:增加按钮来控制拉出和收回抽屉

        override func viewDidLoad() {
            super.viewDidLoad()

            self.view.backgroundColor = UIColor.whiteColor()
            
            navigationItem.title = “主页”
            self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: “Done”), style: UIBarButtonItemStyle.Plain, target: self, action: “doneSlide”)
        }
       
        func doneSlide(){
            
            let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
            appDelegate.drawerController.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)

        }

    针对第三步,我觉得比较难理解的地方是toggleDrawerSlide方法,框架里源代码注释为:

    注释
    Toggles the drawer open/closed based on the drawer passed in. 
      Note that if you attempt to toggle a drawer closed while the other is open, nothing will happen. For example, if you pass in MMDrawerSideLeft, but the right drawer is open, nothing will happen. In addition, the completion block will be called with the finished flag set to NO.
     @param drawerSide The MMDrawerSide to toggle. This value cannot be MMDrawerSideNone.
     @param animated Determines whether the drawer should be toggle animated.
     @param completion The block that is called when the toggle is complete, or if no toggle took place at all.

    自行翻译��,大概意思就是控制抽屉的开关
    ####第四步:使用TableVIew实现左侧划页面
    代码太多,只张贴部分,项目代码可以去源代码下载

      tableView = UITableView(frame: CGRectMake(0, 0,       Common.screenWidth * 0.7, view.frame.height), style: UITableViewStyle.Plain)
    

            tableView.delegate = self
            tableView.dataSource = self
            tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
            view.addSubview(tableView)
            
            //设置headView
            let headImageViewHight: CGFloat = 160
            let headImageView = UIImageView(frame: CGRectMake(0, 0, Common.screenWidth * 0.7, headImageViewHight))
            headImageView.image = UIImage(named: “quesheng”)
            
            tableView.tableHeaderView = headImageView
            //去掉下部空白格
            self.tableView.tableFooterView = UIView()

    第五步:实现视图联动

    在这里实现点击左视图中菜单时,主视图自动联动的功能。采取的措施就是点击不同的Cell,把相对应的视图设置为中心视图

        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
         
            switch (indexPath.row){
            case 0:
                let centerViewController = CenterViewController()
                let centerNavigationController = UINavigationController(rootViewController: centerViewController)
                let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
                appDelegate.drawerController.centerViewController = centerNavigationController
                appDelegate.drawerController.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
            default:
                
                let otherViewController = OtherViewController()
                let otherNavigationController = UINavigationController(rootViewController: otherViewController)
                let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
                appDelegate.drawerController.centerViewController = otherNavigationController
                appDelegate.drawerController.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
            }
          }

    第六步:实现代码重用与优化

    今天时间太紧,代码重用存在一些问题,近期会马上优化,希望可以继续关注

    Paste_Image.png
    如果叙述存在问题,请留言告诉我,谢谢
    代码地址:点个赞哦
    微博地址:互粉互粉

    iOS进阶一百(第四天)

    展开全文
  • swift项目抽屉效果

    2019-06-16 05:48:29
    2019独角兽企业重金招聘Python工程师标准>>> ...

        使用cococaPods导入第三方MMDrawerController 库

        项目中创建Podfile文件中

       pod 'MMDrawerController','~>0.5.7'


     终端中输入

             pod install 下载类库

        OC中导过后可以直接使用,但是swift中由于类库是OC代码不能直接使用。

        需要如下几步解决:

        1.创建新的.h文件,    

        2.删除全部的内容,然后添加  #import "MMDrawerController.h"

        3.点击target->Build Settings->在搜索框中输入bridg->找到Objective-C Bridging Header  中添加.h文件的路径

        在AppDelegate中:

        var drawerController:MMDrawerController!

    然后就封装一个方法:

    func createDrawerController(){

            //设置视图

            let LVC = LeftViewController()

            let CenterVC = MyTabBarViewController()

            

            let CenterNC = UINavigationController.init(rootViewController: CenterVC)

            drawerController = MMDrawerController(centerViewController: CenterNC,leftDrawerViewController: LVC)

            drawerController.maximumLeftDrawerWidth = UIScreen.mainScreen().bounds.width * 0.7

            //添加手势

            drawerController.openDrawerGestureModeMask = MMOpenDrawerGestureMode.All

            drawerController.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.All

            //设置动画,这里是设置打开侧栏透明度从01

            drawerController.setDrawerVisualStateBlock { (drawerController, drawerSide, percentVisible) in

                

                var sideDrawerViewController:UIViewController?

                if(drawerSide == MMDrawerSide.Left){

                    sideDrawerViewController = drawerController.leftDrawerViewController

                }

                sideDrawerViewController?.view.alpha = percentVisible

            }

            

            self.window?.rootViewController = drawerController

            window?.makeKeyAndVisible()

        }


        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {}中调用上面封装的方法,侧滑抽屉效果即可实现(⊙o⊙)哦!





    转载于:https://my.oschina.net/u/2532095/blog/666352

    展开全文
  • 前言之前的几篇博客算是入门篇,那么这篇就是RxSwift的实战篇。由于对RxSwift的认识还不够深刻,所以项目中没有使用MVVM模型,以及编程思想也还没转变过来。...此外,原项目中存在大量强解包,很容易crash。...

    前言

    之前的几篇博客算是入门篇,那么这篇就是RxSwift的实战篇。由于对RxSwift的认识还不够深刻,所以项目中没有使用MVVM模型,以及编程思想也还没转变过来。该项目是参考https://github.com/kLike/ZhiHu-RxSwift实现的,最大的实现区别就是,我用的是纯代码实现,还有对网络请求的封装。此外,原项目中存在大量强解包,很容易crash。因此,我是在原来基础上,做了一些优化,虽然在转模型上没有那么优雅,但是比原来的安全。最后,还是非常感谢该作者源码的贡献~

    框架介绍

    框架 说明
    Moya 对Alamofire的封装
    Moya/RxSwift 针对RxSwift的Moya扩展
    Kingfisher 喵神的网络图片加载库
    HandyJSON 阿里巴巴出的Json转模型库
    RxSwift 这次主角
    RxCocoa 这次主角
    RxDataSources 对原生的UITableviewDataSource的Rx包装
    SwiftDate 处理Date的库
    SnapKit Mansory的swift版
    SlideMenuControllerSwift 侧栏显示

    整体架构搭建

    SlideMenuControllerSwift作为根控制器,侧栏为left VC,tabbarVC为center VC。然后tabbarVC添加两个控制器,一个为首页,一个为其他话题,然后隐藏tabbar,通过侧栏点击切换。如下图所示:

    整体框架

    首页搭建

    1、导航栏的设置

    先来看看效果图:
    首页导航栏效果演示.gif

    刚开始导航栏的颜色是透明的,随着tableView向上滚动时,导航栏主键显示颜色。

    设置代码如下:

    • 获取导航栏的背景图,用于滚动时修改颜色和透明图
    • 设置barTintColor为蓝色
    • 设置barTintColor为白色
    barImg = (navigationController?.navigationBar.subviews.first)!
            barImg.alpha = 0
            navigationItem.title = "今日要闻"
            navigationController?.navigationBar.tintColor = UIColor.white
            navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
            navigationController?.navigationBar.shadowImage = UIImage()
            navigationController?.navigationBar.barTintColor = UIColor.rgb(63, 141, 208)
            navigationController?.navigationBar.isTranslucent = false

    样式设置完后,开始监听tableview的滚动

    tableView.rx
            .contentOffset
                .map { $0.y }
                .subscribe(onNext: { y in
                    self.barImg.alpha = y / 200
                })
            .addDisposableTo(disposeBag)

    2、轮播图

    2.1、轮播图的实现原理

    首先头部的轮播图是使用UICollectView和pageControl实现的,只要对数组的首尾做处理,即可实现无线轮播的效果。
    例如,图片有1,2,3三张图,但是实际上,模型是有3,1,2,3,1五张图片。那么只要显示第一张或最后一张时,马上修改collectView的contentOffset即可瞒天过海,具体实现参考项目代码吧~

    2.2、向下拖拽时,图片会放大

    其实也是监听tableView的滚动,改变轮播图中图片的高度即可。

    1、监听滚动,将offsetY绑定给轮播图的Variable属性

    tableView.rx.contentOffset
                .filter { $0.y < 0 }
                .map { $0.y }
                .asDriver(onErrorJustReturn: 0)
                .drive(bannerView.offY)
                .addDisposableTo(disposeBag)

    2、监听Variable属性的变化,修改图片的高度和y坐标

    offY
            .asObservable()
                .subscribe(onNext: {
                    offY in
                    self.collectionView.visibleCells.forEach({ (cell) in
                        let myCell = cell as! BannerCell
                        myCell.imgView.frame.origin.y = offY
                        myCell.imgView.frame.size.height = 200 - offY
                    })
                }).addDisposableTo(dispose)

    3、自动加载更多

    我在tableView的willDisplay方法中,监听section的变化,刷新条件是:当滚动到最后一个section的第一个元素时,加载更多数据

     func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            // 滚动到最后一个section的第一个元素时,加载更多数据
            if indexPath.section == modelArr.value.count - 1 && indexPath.row == 0 {
                loadMoreData()
            }

    这里,顺便说一下我的网络加载封装。使用Moya,可以优雅的封装Alamofire,而Moya/Rxswift可以将返回的结果转为Observable属性,进行监听。那么针对上拉刷新,我是这样封装的,在我的MPApiService服务层中,定义了如下方法:

    func loadMoreHomeNewsList(date: String) -> Observable<MPStoryListModel> {
            return provider.request(.getMoreHomeList(date))
                .flatMapLatest { (reponse) -> Observable<MPStoryListModel> in
                    guard let dic = try? reponse.mapJSON() as? NSDictionary else {
                        return Observable.error(MPError.parseJsonError)
                    }
                    guard let list = MPStoryListModel.deserialize(from: dic) else {
                        return Observable.error(MPError.parseJsonError)
                    }
                    return Observable.just(list)
            }
        }

    使用时,在HomeVC是这样调用的

    fileprivate func loadMoreData() {
            MPApiService.shareAPI.loadMoreHomeNewsList(date: newsDate)
            .asDriver(onErrorJustReturn: MPStoryListModel())
                .drive(onNext: { (model) in
                    if let stories = model.stories, let date = model.date {
                        self.modelArr.value.append(SectionModel(model: date, items: stories))
                        self.newsDate = date
                    }
                })
            .addDisposableTo(disposeBag)
        }

    使用了Driver,之前也提过Driver是转为UI层设计的,所有的操作都会在主线程操作。如果使用subscribe监听的话,需要设置在哪个线程操作。是不是代码有点繁琐?其实我也这么觉得,初入RxSwift,不打算封装太多层,怕把自己绕进去了,所以就先这样写了~

    4、设置导航栏的titile日期

    效果说明:随着列表的滚动,sectionHeader的日期会显示在导航栏上,滚动到最新日期时,导航栏又显示回今日要闻。

    同样地,需要在tableView的willDisplay方法做监听,监听方法如下:

    1、获得当前列表显示的最小section

           func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            // 获得当前列表显示的最小section
            DispatchQueue.global().async {
                if let value = (tableView.indexPathsForVisibleRows?.reduce(Int.max) { (result, ind) -> Int in return min(result, ind.section) }) {
                    self.titleNum.value = value
                }
            }
        }

    2、对titleNum做监听

    titleNum.asDriver()
                .distinctUntilChanged()
                .drive(onNext: { num in
                    if num == 0 {
                        self.navigationItem.title = "今日要闻"
                    }else {
                        let date = DateInRegion.init(string: self.dataSource[num].model, format: DateFormat.custom("yyyyMMdd"))!
                        self.navigationItem.title = "\(date.month)月\(date.day)日 \(date.weekday.toWeekday())"
                    }
                })
                .addDisposableTo(disposeBag)

    为了防止多次响应,调用distinctUntilChanged,正如字面的意思,就是数值不一样时才响应。

    总结

    这一篇就只介绍首页吧,基本上涵盖了所有首页的要点了,另一篇点击详情页可阅。其他的,可以看项目代码,源码地址:https://github.com/maple1994/RxZhiHuDaily

    展开全文
  • 介绍 苹果在2014年与iOS 8... 本教程要求您至少将Swift 3与Xcode 8结合使用。您还需要具有用于测试的物理iOS设备和Apple开发人员帐户,以便您可以为应用程序启用CloudKit。 1.为什么要使用CloudKit? 首先,我...

    介绍

    苹果在2014年与iOS 8一同推出了自己的CloudKit框架。尽管其主要目的是充当iOS应用程序的在线数据库,但CloudKit还提供了许多其他功能,包括推送通知。

    本教程要求您至少将Swift 3与Xcode 8结合使用。您还需要具有用于测试的物理iOS设备和Apple开发人员帐户,以便您可以为应用程序启用CloudKit。

    1.为什么要使用CloudKit?

    首先,我们将研究为应用程序的推送通知使用CloudKit的优点(和缺点)。

    在本教程中将看到,要使用CloudKit设置推送通知,您无需像其他云服务一样担心创建证书和置备配置文件。 由于一切都是由Apple制造的,因此您要做的就是为您的应用程序启用CloudKit,其余的都可以使用。

    对于某些开发人员而言,CloudKit最好的事情之一就是您免费获得多少。 还有许多其他的后端即服务(BaaS)公司,它们为iOS应用提供推送通知,但是其中大多数公司都限制了可以免费发送多少个通知。 使用CloudKit,可以发送给用户的推送通知数量不受限制。 但是,CloudKit的免费套餐确实限制了数据存储,数据传输和每秒的用户请求数。

    在您的应用程序中使用CloudKit的另一个优点是,由Apple提供的网络稳定性和维护将是您永远不必担心的事情。 Apple服务中断很少发生,并且需要立即解决。 这意味着您可以依靠CloudKit始终为您的用户正常工作。

    2.设置CloudKit

    首先,从iOS>应用程序> Single View Application模板在Xcode中创建一个新项目。

    Xcode创建项目后,请转到项目导航器 ,然后单击“ 功能”选项卡。 在此屏幕上,单击开关以启用iCloud ,然后启用CloudKit复选框:

    启用iCloud和CloudKit

    启用CloudKit后,现在可以转到应用程序的CloudKit仪表板

    为了向应用程序的用户发送推送通知,我们将创建一个GlobalNotification记录类型,该记录类型将在创建这种类型的新记录时通知所有用户。 如果登录后尚未为您打开CloudKit仪表板的“ 记录类型”部分,请在侧栏中单击它。

    要创建新的记录类型,请点击+   屏幕顶部的按钮。 填写菜单,如以下屏幕截图所示:

    全局通知记录类型

    对于本教程,我们仅将单个内容字段添加到记录类型,但是对于您自己的应用程序,您可以根据需要添加任意多个。

    完成后,单击右下角的“ 保存”按钮。

    3.设置应用

    返回Xcode,打开您的AppDelegate.swift文件,并在代码顶部添加以下import语句:

    import CloudKit
    import UserNotifications

    接下来,编辑您的AppDelegate类定义,使其符合UNUserNotificationCenterDelegate协议:

    class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
        ...
    }

    现在,我们需要请求权限才能显示通知。 这样做,用以下替换您的application(_:didFinishLaunchingWithOptions:)方法:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound], completionHandler: { authorized, error in
            if authorized {
                application.registerForRemoteNotifications()
            }
        })
        
        return true
    }

    使用此代码,我们要求用户获得显示通知的权限,如果他们接受,则注册该应用程序以获取推送通知。

    现在,我们需要实现application(_:didRegisterForRemoteNotificationsWithDeviceToken:)方法。 将以下代码添加到您的AppDelegate类中:

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let subscription = CKQuerySubscription(recordType: "GlobalNotification", predicate: NSPredicate(format: "TRUEPREDICATE"), options: .firesOnRecordCreation)
        
        let info = CKNotificationInfo()
        info.alertBody = "A new notification has been posted!"
        info.shouldBadge = true
        info.soundName = "default"
        
        subscription.notificationInfo = info
        
        CKContainer.default().publicCloudDatabase.save(subscription, completionHandler: { subscription, error in
            if error == nil {
                // Subscription saved successfully
            } else {
                // An error occurred
            }
        })
    }

    使用此代码,我们首先创建一个CKQuerySubscription对象。 这个订阅对象告诉CloudKit它应该发送通知的内容。 初始化此订阅时,我们包括以下内容:

    • 要监视的记录类型的名称。
    • 谓词,可用于将预订限制为指定类型的特定记录。 在本教程中,我们希望订阅所有GlobalNotification记录,因此我们传入始终为真的谓词。
    • 一个或多个触发器告诉CloudKit应何时发送通知。 在此示例中,我们只希望在创建新记录时发出通知。 其他有效触发器包括何时更新或删除记录。

    接下来,我们创建一个CKNotificationInfo对象,为其提供一些内容,然后将其分配给订阅对象。 CKNotificationInfo对象是您格式化传递给用户的推送通知的方式。 在此示例中,我们使用以下属性对其进行配置:

    • alertBody "A new notification has been posted!"
    • shouldBadge值为true 这将导致主屏幕上的应用程序图标针对收到的每个通知增加其编号。
    • soundName"default" 这只会为您的应用使用默认的iOS通知声音。 如果要使用自定义声音,则将需要使用声音文件的名称。
    • 具有单个值的desiredKeys数组。 对于您包含在此数组中的每个键,CloudKit将从触发通知的记录中加载相应的值,并将其包含在通知的用户信息字典中。

    再往下,我们将通知信息分配给订阅,然后将其保存到您的应用程序的公共CloudKit数据库中。

    为了在您的应用程序运行时可以看到通知,请在AppDelegate类中添加以下方法:

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound])
    }

    此代码使用UserNotifications框架来显示您的通知,就好像您的应用程序根本没有运行一样。

    在运行您的应用程序之前,您需要通过转到设置来检查您的测试设备是否已登录到iCloud帐户。 否则,您将需要这样做,因为CloudKit API要求当前用户登录。

    从Xcode构建并运行您的应用,并接受您的应用显示通知的请求。 完成此操作后,请返回您应用的CloudKit仪表板,然后单击左侧边栏中的“ 订阅类型 ”。 您应该看到带有INSERT触发器的GlobalNotification记录的新订阅:

    订阅类型

    4.发送通知

    现在,剩下要做的就是发送通知! 仍在CloudKit仪表板中,单击左侧栏中公共数据下的默认区域 单击+按钮或“ 新建记录”以创建新的GlobalNotification记录。 随便填写内容 ,然后单击右下角的保存

    保存记录后,您应该看到通知立即出现在测试设备上:

    通知

    结论

    如您所见,您可以使用CloudKit轻松为iOS应用实现推送通知。 设置非常简单,仅需很少的步骤,并且提供的API允许您为应用程序可能需要的任何推送通知。

    翻译自: https://code.tutsplus.com/tutorials/using-apples-cloudkit-for-push-notifications--cms-28125

    展开全文
  • 这个Demo包含一个主页和详情页,其中MenuViewController继承自UITableViewController,它主要用于展示左边侧栏,自定义的MenuItemCell中设置了每一个菜单的图标和颜色。DetailViewController为详情页,显示了每个...
  • 一直想写这么一个东西,长期以来我发现很多初学者的问题在于不掌握学习的方法,所以,Xcode那么好的SDK文档摆在那里,对他们也起不到什么太大的作用。从论坛、微博等等地方看到的初学者提出的问题,也暴露出他们不...
  • 在上一篇关于使用Google Cloud AutoML训练图像标签模型之后,我们将研究如何训练另一种模型来识别和定位图像中的对象,即对象检测模型! 与图像标记(或图像分类)相反,在该模型中,模型根据某些类别或类别标记...
  • 尽管这曾经是Flash的领域-导致很多加载时间和潜在的兼容性问题,但HTML5已Swift成为创建动画和交互式 Web内容的主要方法。 当然, 并不是每个人都有时间或技能来编写HTML5内容。 如果您是其中的一员,也许...
  • 1. 什么是扩展? 扩展( Extension )是 iOS 8 中引入的一个非常重要的新特性。扩展让 app 之间的数据交互成为可能。用户可以在 app 中使用其他应用提供的功能,而无需离开当前的应用。在 iOS 8 系统之前,每一个...
  • 转载自:http://www.cocoachina.com/ios/20150106/10839.html Cocos开发者平台 Cocos引擎中文官网 H5轻游戏平台 ... 8 Swift App Store Apple Watch Metal Cocos引擎 手游
  • iina mac版是一款采用现代设计和流线型功能的在线视频播放器,可以观看视频,管理播放列表,处理媒体内容或为电影加载字幕提等等。iina mac可以加载本地文件或提供视频URL,iina ...下载好IINA镜像包后,点击打开II...
  • 北京时间 6 月 5 日凌晨 1点,备受瞩目的苹果 WWDC 2018 全球开发者大会在美国加州圣何塞 McEnery 会议中心正式拉开帷幕...在发布之前,库克表示今年是Appstore十周年,目前Appstore每周5亿次的点击量,开发者从App ...
  • 可以选择喜欢的主题,点击进入到它的 github 地址,只需要把 GitHub 的地址复制下来即可。 我选择的主题为:hexo-theme-next,所以下面的配置也会以 next 为例。 2.克隆主题 再打开Hexo文件夹下的themes目录(F:\...
  • 原文:How to read Apple’s developer documentation 对于很多人来说,这篇文章听起来很奇怪,因为我们已经习惯了 Apple 的 API 文档的工作方式,因此我们精神上已经经过调整以快速找到我们想要的东西。...
  • 原文:How to read Apple’s developer documentation 对于很多人来说,这篇文章听起来很奇怪,因为我们已经习惯了 Apple 的 API 文档的工作方式,因此我们精神上已经经过调整以快速找到我们想要的东西。...
  • 编程工具的常用插件

    2019-09-26 15:10:08
    Visual Studio Code 该编辑器也集成了所有一款现代编辑器所应该具备的特性,包括语法高亮(syntax high lighting),可定制的热键绑定(customizable keyboard bindings),括号匹配(bracket matching)以及代码...
  • 收藏的Flex网站

    2016-03-09 10:33:16
    Bookmarks   3d   3dmax   3dmax打造立体金属文字倒角效果 - 闪吧教材 入门教程:3dmax打造文字挤出效果 - 闪吧教材   PaperVision3D   forum.papervision3d.org - Index ...3dmax打造
  • 本文是我学习《iOS Animations by Tutorials》 笔记中的一篇。 文中详细代码都放在我的Github上 andyRon/LearniOSAnimations。 到目前为止,之前的文章只使用了二维动画——这是在平面设备屏幕上动画元素的最自然...
1 2
收藏数 24
精华内容 9
关键字:

swift侧栏框点击事件