美文网首页
Swift新手可能遇到的问题

Swift新手可能遇到的问题

作者: 志超mike | 来源:发表于2016-07-02 10:52 被阅读2176次

    这是用Swift做项目遇到的问题记录,主要是供自己记录,如果有人碰巧搜索看到,有些你可能看不懂。不过这也没关系,因为所有问题是基本都是在stackoverflow找到的答案,所以你去查就是了。

    一些开发过程经验:
    1)关于唯一识别的问题,通常使用 NSUUID, 例子: let uuid = NSUUID().UUIDString. 至于使用objectid作为唯一标示还未弄清楚,因为查询多个结果时,其objectid是编号的。

    1. 关于tableView的行删除,先要保证数据源的数据以删除才能删除行。否则出错“ Assertion failure in -[UITableView _endCellAnimationsWithContext:
      请参看帖子:http://blog.sina.com.cn/s/blog_7b9d64af0101b6se.html

    3) 页面跳转方式:
    a) 采用在storyboard跳转方式
    let storyboard = UIStoryboard(name: "Main", bundle: nil); let vc = storyboard.instantiateViewControllerWithIdentifier("login") as UIViewController;
    self.navigationController?.pushViewController(vc, animated: true) (push)
    // self.presentViewController(vc, animated: true, completion: nil) (modal)
    b)采用segue方式
    self.performSegueWithIdentifier("segueShowRemind", sender: self)

    c) 如果只是为了刷新数据,可以直接再次调用 viewdidload

    4)ttt

    5)获取coredata数据时的排序方式:1) http://stackoverflow.com/questions/25548587/sorting-array-received-from-core-data-in-swift ,2)http://www.bubuko.com/infodetail-566143.html, 3)http://www.linuxidc.com/Linux/2015-09/122778.htm

    6)关于数据刷新,每次在viewWillAppear执行reload tableView是不合适的,性能影响大,应该用其他方式,比如 http://blog.sina.com.cn/s/blog_7b9d64af0101b82p.html

    1. 关于NSDate与String的转换,需要注意自定定义数据格式,否则从NSDate转不出字符。
      let dateFormat: NSDateFormatter = NSDateFormatter() dateFormat.dateFormat = "yyyy-mm-dd HH:mm:ss EEEE"
      var time:String = dateFormat.stringFromDate(date)

    8)关于 coredata查询句子的语法, 条件查询是用 &&, || 等,代码参考:

    9) 关于codedata的数据查找,注意条件的格式,对于整型、字符的条件,其使用格式不一样。比如下面错误提示,就是等号右侧未加引号,因为id定义是String。 Unable to parse the format string "uid = F657D3B0-F482-44B2-B0FC-5FC1FBFF28C4"'

    10) 关于变量 optional定义,会引入optional字符,导致数据错误。如果打印输出发现有optional,在变量后增加!即可。

    1. 在vc隐藏tabbar,bottom bar的方法:http://segmentfault.com/a/1190000000327529
      a.最简单就是直接在storyboard 设置“hide bottom bar on push”,
      b. 在上级vc viewdidload增加 : self.hidesBottomBarWhenPushed = true //隐藏低栏

    2. 如何调整nav bar的高度,关联outlet,然后 navigationBar.frame = CGRectMake(0, 0, 100, 80)

    13)设置static table,关联tableViewVC后,记得不里面关于表格的代码屏蔽,否则就不显示内容。

    1. 设置tableview的table的section的距离(间距) :http://blog.csdn.net/jimy86022/article/details/21702051

    15)关于userdefault临时存储东西,在appdelegate先进行初始化,这样后面调用就不容易出现问题。

    16)注意在auto layout情况下,如果没有设定好constraint在模拟器上显示不完整的,所以就看不到了。比如如果在tableView没有设定与view的constraint,滑动删除按钮因为在最右边,所以看不到。

    17)登录界面的过渡(segue)用户modal,取消/成功用户unwind过渡,unwind是个IBAction 。 而一般表格点击到新页面用户prepareSegue。

    18) 关于模拟器输入法选择,在模拟器中选择setting,即像手机那样操作。

    关于蓝牙链接的文章:
    a. 建立连接的文章:http://2goo.info/weblog/detail/232351
    b. 最佳实践:http://southpeak.github.io/blog/2014/08/01/core-bluetoothkuang-jia-zhi-san-:zui-jia-shi-jian/

    1. 关于事件捕捉,比如关闭键盘;当tableview上的textField,用户touchEnd方法是没办法关闭键盘的,如下有两种方式可以通过识别手势从而触发关闭键盘代码:
      a: 通过捕捉tableview滚动的事件,然后触发(推荐)。
      func scrollViewWillBeginDragging(scrollView: UIScrollView)
      b: 通过 UITapGestureRecognizer 定义一个手势,然后绑绑定到tableview

    20)用代码定义导航栏上的左右按钮,
    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Refresh, target: self, action: "refresh")

    关于蓝牙功能

    服务UUID****:****Device Informationservice: <CBCharacteristic: 0x1653fd80, UUID = PnP ID, properties = 0x2, value = (null), notifying = NO>****
    服务UUID****:FFE0

    21) webView访问地址时,会涉及访问权限的错误,

    22) 如何在auto layout把3个view平均分布在界面上 https://lvwenhan.com/ios/431.html

    1. 图表控件,charts, 用pod安装后,要先run一次,才能import,在github已经提过

    2. iOS 9 集成社会化分享的若干问题

    http://wiki.mob.com/ios9-%E5%AF%B9sharesdk%E7%9A%84%E5%BD%B1%E5%93%8D%EF%BC%88%E9%80%82%E9%85%8Dios-9%E5%BF%85%E8%AF%BB%EF%BC%89/

    当前还是用openshare比较简单,但还有集成问题为解决。

    25)指定日期格式显示,可看看如下帖子:
    http://my.oschina.net/yongbin45/blog/150667

    1. 关于“OBJC_CLASS”、“linker command failed with exit code1”的问题
      自己这边原因是引入openshare库的问题,用pod引入的并不生效,自己在xcode拷贝文件夹的方式就生效了。

    2. leanCloud的表在创建第一条数据时就已经明确了数据的类型,特别是索引,所以后续数据必须按照执行

    28) 关于iOS信息推送设置:
    a. 按照leanCloud的证书设置指南,把测试和生产的证书制作出来,即push service两个,app develop两个。
    b. 按上面操作在网页生成cer文件,双击证书会添加到“钥匙串访问 ”。
    c. 在xcode设置应用使用的证书(上iTunes要用正式证书),http://www.jianshu.com/p/986e02d38f1b
    d. 在leanCloud导入证书,有一点要注意的是,测试时 LC和APP都用户测试证书,上线就都用正式证书。

    29)从LC获取图片,使用下面方法
    a. 通过Url方为
    func demoCombineQiniuApi() {
    getDemoFile { (file) -> Void in let thumbnailFile = AVFile(URL: "(file!.url)?imageView/1/w/50/h/100") thumbnailFile.getDataInBackgroundWithBlock({(data: NSData?, error: NSError?) in if self.filterError(error) { let image: UIImage = UIImage(data: data!, scale: UIScreen.mainScreen().scale)! self.showImage(image) self.log("成功用七牛接口获得缩略图") } }) }
    }
    b. 通过objectId
    func getDemoFile(block : (file: AVFile!) -> Void) { AVFile.getFileWithObjectId("5573fddee4b06a32094af62b", withBlock: { (file: AVFile?, error: NSError?) -> Void in if self.filterError(error) { block(file:file) } })
    }

    30)关于图片压缩,

    whatsapp的图片压缩: https://www.built.io/blog/2013/03/improving-image-compression-what-weve-learned-from-whatsapp/

    1. 关于图片的全屏展示,可参考leanStorageDemoSwift的“ showImage”方法

    关于创建、修改提醒时,图片处理逻辑:
    重点:要上传的图片应该放在userDefault的“upLoadImage”里。
    0)按钮有默认的图片。
    1)新创建提醒
    a. 选择图片,把图片缓存到userDefault, 界面从useDefault读取显示

    1. 修改提醒
      a. 从网络获取图片,如果值不为nil,就赋值给userDefault

    不管哪种情况,保存时判定一下userDefault的upLoadImage的值是为为空。

    32) 关于segue返回上两步的方案, 见这个文章
    http://stackoverflow.com/questions/7005787/how-to-identify-previous-view-controller-in-navigation-stack

    33)UITextVIew的应用 (自动修改长度,自动判断连接、电话、email)

    自动判断高度:直接autolayout就可以

    识别连接:http://stackoverflow.com/questions/5964434/how-to-a-clickable-url-email-phone-number-on-uitextview

    34) 自定义TabBar

    http://www.jianshu.com/p/e81547c3eda7

    插件:类instagram https://github.com/boctor/idev-recipes/tree/master/RaisedCenterTabBar

    tabbar动态效果:https://github.com/Ramotion/animated-tab-bar

    more插件: http://code4app.com/ios/Raised-Center-Tab-Bar/4f68162c6803fa791c000003

    1. 导航条的颜色修改,见下连接; 关于如何修改icon的颜色,可以修改图片也可以把它定义为模板,然后调整色值
      http://www.cocoachina.com/ios/20150703/12363.html

    直接一次性修改导航背景颜色,用代码可看这里 :https://developer.xamarin.com/recipes/ios/content_controls/navigation_controller/change_the_nav_bar_color/

    36) 在tableHeadView展示textView(自适应内容size)
    a) 正常把textView拖到headView内,不勾选“scroll enabled”。
    b ) 设置 上下左右的autolayout,注意不要设置高度。 就着两步,就可以实现textView的自适应。

     c )接下来的问题主要是如下使上层的view能够自适应高度,用下面两句代码就可以实现。
            let s = tableHeadView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
        print(s.height)
        tableHeadView.frame.size.height = s.height
            简单而已就是重新获取view内元素的高度,然后刷新view高度。 需要注意view内的其他元素,比uilabel如果显示多行的话,其高度需要被刷新,因为view并没有统计变化后的高度。
           如果UILabel超过1行,代码举例: remindTitle.sizeToFit()
    

    37) 在tableHeadView展示图片,在autolayout下让图片在屏幕宽度基础上比例输出
    1. 首先计算出原图片 高度、宽度和宽高比。 (例子: let imageHeight = imageView.image?.size.height)
    2. 因为用户了autolayout,通过imageView.frame并不能获取图片在手机展示的真实尺寸,所以采用折中方法从screen获取,如 let rect = UIScreen.mainScreen().bounds.size.width
    3. 屏幕的宽度与autolayout的imageView宽度差不多,所以就可以用屏幕宽度和图片比例计算出imageView的高度。
    4.还有一个要注意,因为在autolayout为了避免constraint出错,所以给imageView设置了固定高度,并建立IBOutlet,如 @IBOutlet weak var imageHeightContraint:NSLayoutConstraint?, 所以步骤3计算的值就给这里赋值。

    38) 关于tableViewCell插入图片时,其高度的问题,正常做法用subclass保存cell,然后在cell设置auto layout,在程序运行时修改constraint。 我目前做法没有设subclass,不设置image的高度,但auto layout就报红色,但目前运行没影响。

    39) 在button增加action时,遇到crash情况,原因是对应方法如果有参数,就要增加冒号,如下所示。
    func likeCheckIntemp(sender:AnyObject) {}
    cell.likeButton.addTarget(self, action: "likeCheckIntemp:", forControlEvents: UIControlEvents.TouchUpInside)

    40)UITableViewCell图片加载错乱问题
    http://stackoverflow.com/questions/16663618/async-image-loading-from-url-inside-a-uitableview-cell-image-changes-to-wrong

    1. 用xib后,在checkIn列表点击comment按钮,sender的值不同,原来是button,用户xib后是整个VC
      貌似可以用如下方法解决,在button增加tag,传值时传过去:http://stackoverflow.com/questions/24814646/attach-parameter-to-button-addtarget-action-in-swift
      进展:暂还不要连接的解决方式,因为问题是自己在segue传值时没把值传过去,按下面传过去就好。
      func commentCheckIn(sender:AnyObject) { self.performSegueWithIdentifier("segueToComment", sender: sender)
      }
      42) 关于tableView的自动行高,如下面代码;如果label要多行,在storyboard上选line=0

      self.tableView.rowHeight = UITableViewAutomaticDimension;
      self.tableView.estimatedRowHeight = 44.0; // 设置为一个接近“平均”行高的值

    2. 在UITableViewController上定义底部toolbar问题: 1)toolbar有跳跃才回到底部。2)而且影响previous的view。经过多次尝试,最后在该tableViewVC定义其位置,在viewWillDisappear隐藏toolbar

    44) 在tableView删除某行时,出错“ Invalid update: invalid number of rows in section 0 ...” 大概意思是删除时行数不一致造成错误

    1. 补充记录,如何使用XIB?
      1. 首先创建xib文件和对应swift文件
      2. 对应tableViewCell,要先在storyboard的cell上选择class和identifier与xib相一致
      3. 在swift文件的cellForRowIndexPath 注册xib文件,样式如下:
        tableView.registerNib(UINib(nibName: "RemindListTableViewCell", bundle: nil), forCellReuseIdentifier: "RemindListCell")
        let cell = tableView.dequeueReusableCellWithIdentifier("RemindListCell", forIndexPath: indexPath) as! RemindListTableViewCell

    45)点back时的反向传参数 (通过代理实现实时传参数)
    http://stackoverflow.com/questions/24298413/how-to-pass-information-back-in-ios-when-reversing-a-segue-using-swift

    这个实现方式更代码更少
    http://stackoverflow.com/questions/24318480/passing-data-in-swift/24318588#24318588

    6步实现代理简单教程 http://www.jianshu.com/p/b077bcd4b168

    46) 关于下级VC修改要同步到上级VC的问题,只要通过segue把数据传递,并且上级返回时没有重复取值,下级的修改会直接同步到上级VC,因为他们实际是同一值,存在同一个内存区。

    46)触发提醒的最合适时机是基于使用场景。详细见文章:
    http://techcrunch.com/2014/04/04/the-right-way-to-ask-users-for-ios-permissions/

    47) iOS的推送问题排查,请看这里:
    https://leancloud.cn/docs/push_guide.html#推送结果查询

    48)如何在自己项目添加playground? 大概意思就是用playground调用项目函数
    https://medium.com/@LogMaestro/adding-playgrounds-to-your-xcode-project-79d5ea0c7087#.n38qa9dfw

    1. 关于deviceToken获取,installation表更新逻辑
      a. 不管是在app调用注册通知,还是用户刚开始没注册,然后在setting点启动,app都会在调用appDelegate的registerRemoteNotification获取deviceToken
      b. 我们要做的是在启动和登录时增加一个判断,在installation表保证uid、deviceToken的对应上,并且是唯一性,老记录要删除。

    50) 关于缓存方案, 有文章说,先在viewdidload加载所要的数据并且缓存,然后在viewwillappear

       思考: 1. 单个提醒信息,缓存5分钟;修改时直接修改变量并且异步保存到服务器。
    
    1. 由于保存图片出错,出现右边错误值Optional(<null>),在后台看是空,但又不是nil。 找了个判断方法,通过长度来判断。
      看下例子: //正常情况用不到,紧在保存照片时crash时才会导致出现null var imageNull = false if remindLC.valueForKey("image") is NSNull { imageNull = true
      }

    52)关于在checkFlow页点击“评论”,在评论页不显示 toolbar的问题,经过反复尝试,目前找到解决方法是在checkFlow上层的navigation view的 storyboard设置 show toolbar, 然后后续push就有了。。但要注意后续想显示bar的页面需要hidden掉。

    53) 经验:

    1. 自己项目在showRemind有设置unwind segue的IBAction “close”,然后在修改remind页只要设置segue并且指定“close”就能跳转showRemind,即使相隔了一个remindInfo的VC
      2.没有segue连接也能跳转,夸view的unwind segue: 在storyboard右键点击showRemindd”exit”,然后可以拖着连接任何VC的Action,估计连接后就能到showRemind。 (这个还木有时间试)
      关于unwind:http://stackoverflow.com/questions/12561735/what-are-unwind-segues-for-and-how-do-you-use-them

    54) 关于在toolbar位置 发信对话框的实现经验。 这个问题最近修改时间花了1周,之前也折腾了1周, 总结教训是没有很好地从基层原理去了解,总希望找个控件就实现。 在实现过程中发信tableViewVC的实现比较麻烦,但由于不想切换到UIViewVC导致浪费了很多时间,其实在stackOverFlow的经验都是用UIView实现的。 不过经过这次,自己对frame位置变化,view什么时候加载、键盘变化、textViewChange等有比较深刻的认识。

    1. 修改app名字,

    方法1:在info.plist文件修改 bundle display name https://developer.apple.com/library/ios/qa/qa1823/_index.html, 应该是

    方法2:在target的build setting,可以设debug、release的名字,在Xcode是出debug名字,如何出release名字?

    1. 关于coreData数据保存: 只要创建了对象,数据库就会增加一行数据,所以如果remindId字段是在后续刷新,并且不能保证100%刷新,就会出现后续调用remindId出错crash情况。由于目前在保存是没找到处理该问题的好方法,所以统一在app启动时,把remind表中没有remindId的行删除。

    57) 关于EULA, 好不容易找到一个用户协议的模板。 http://www.wandoujia.com/ios/eyepetizer/agreement.html ““开眼”软件用户协议”

    1. 如何使用SearchBar and Search Display Controller, 请看视频:https://www.youtube.com/watch?v=N9wcKc37ZXI,帖子: https://grokswift.com/swift-tableview-search-bar/

    58) 水印功能实现,在简书找到别人共享代码,目前发现问题是 图片实际尺寸7501334,但在UIImage.size显示尺寸1/2, 即375667。。经过调试只用用10801920图图片放到x2位置,那么在不同尺寸模拟器运行时都会是540960的size。所以就用这尺寸来制作水印。

    59) 关于调用其他VC的方法,之前不知道其实在Functions.swift里的functions就是VC方法,现在又增加了WaterMarkVC.swift,日后应用可以把以前访问checkInTableViewCell的那些请求做修改。

    1. 关于leanCloud的静态库、动态库引用问题: 之前一直是用静态库, 因为微信登录原因需要使用leanCloudSocial库,先引入静态发现无法引入,再引入动态发现一堆错误。后来经过与leancloud的人论坛交流,采用动态库后可用。

    要注意:
    1)相同的库,静态和动态只能选其一,因为是冲突的。
    2)静态库的引用是在header文件上import(带路径),动态库是在每个文件头部import (无需路径)
    注意:帖子上说 动态库不能用:https://forum.leancloud.cn/t/ios-sdk-swift/7589

    61)可能是更新了cocoaPod引入问题,运行时有20多个错误,但在iPhone5模拟器、iPhone6s手机没有问题。感觉是跟armv7、i386架构相关,后来在building settings 的valid architectures 增加“x86_64, i386” 然后就可以了。

    1. 问题: ** a valid provisioning profile** for this excitable was not found,不知为为啥这个问题,实际上我的证书的木有问题的,自己处理是分别在project和target的 “Code Signing”重设一下就下,一般是选自动就好

    相关文章

      网友评论

          本文标题:Swift新手可能遇到的问题

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