PresentViewController提供一个半透明的viewcontroller

相信不少人的项目里都会有这样一个需求,例如做个自己的actionsheet,或者弹出个自己做的分享页面,苹果自己的办法就是用presentviewcontroller提供一个新的controller,例如alertController。而当我们需要自己做的时候,就可以有两种方法,一种是addSubview,同时利用动画来实现,这样也可以做到很不错的效果,但毕竟不是官方做法,所以这里不做详解,我们主要来讨论下官方用法,利用presentViewController的方法来展示一个新的controller。

很多人可能会直接就这样写了:

let vc = whatEverNameViewController()
vc.view.alpha = 0.5
self.presentViewController(vc, animated: true, completion: nil)

这样很简单,你会发现你得到了一个黑屏,于是你转而Google一下,发现绝大多数解决方法都是说利用storyboard ID来声明VC,当然这样确实是一个解决办法,但如果就是没用storyboard而是用手写的VC呢,于是继续Google,发现要设定modalPresentationStyle,于是你手指翻动,加上了这样一句:

self.modalPresentationStyle = .CurrentContext

加上之后跑一遍,结果只有动画过程中半透明,动画结束了还是黑屏,原来,这个只是IOS7之前的写法,在IOS8及以后的版本中,apple为了配合自己的alertController,将这个方法从rootViewController中移到了展示的controller中,所以正确的写法现在变成了这样:

let vc = whatEverNameViewController()
vc.view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
vc.modalPresentationStyle = .OverCurrentContext
vc.modalTransitionStyle = .CoverVertical
self.presentViewController(vc, animated: true, completion: nil)

注意到一个小小的不同了么?是的,不要直接设定view的alpha值,这样会导致所有的subview都变得透明,而应该是backgroundColor的alpha值,这样subview便不会受到影响。
至于怎么返回上一个VC,其实只要使用dismissViewControllerAnimated这个方法就可以,加个tap手势或者加个按钮事件都可以

Swift 2.2 is available now!

在这个让人略失误的let us loop you in 发布会之后,苹果开放了包含Swift 2.2 版本的Xcode7.3版本的下载。这是Swift开源之后的第一次发布官方版本,这也是第一个包含非Apple官方程序员贡献者的版本,根据Release notes的统计,该版本共包含了212位非Apple官方程序员的贡献,包括但不限于以下几个:

虽然在之前的snapshot版本中,swift2.2包含了swift自己的包管理工具Swift Product Manager(以下称SPM),但是包含在Xcode7.3中的swift2.2并未包含SPM工具,想使用最新的swift toolchain管理包的同学只能去下载swift3.0的snapshot了

有关Swift2.2版本方面的代码方面的改变:

  • 移除C语言风格的for循环,同时移除++和–操作符,包括前置与后置,将在3.0版本中彻底停用
  • 函数方法将不能直接声明为柯里化参数列表, 而是需要返回一个相同参数的函数方法.

这里用代码举例解释一下:

func doGET(url: String, completionHandler: ([String]?, NSError?) -> ()) {
    // do a GET HTTP request and call the completion handler when receiving the response
}
func completionHandler(results: [String]?, error: NSError?) {
    self.results = results
    self.resultLabel.text = "Got all items"
    self.tableView.reloadData()
}

func getAll() {
    doGET("http://blog.swiftflamel.com", completionHandler)
}

这样的写法在swift2.1及以前都是被认同的,但是在2.2版本中,这种写法将无法被编辑器识别,将直接报错,而之后只能使用如下这种写法:

func completionHandler(text: String) -> ([String]?, NSError?) -> () {
    return {results, error in
        self.results = results
        self.resultLabel.text = text
        self.tableView.reloadData()
    }
}
func getAll() {
    doGET("http://blog.swiftflamel.com", completionHandler("Got all items"))
}

而在swift2.1版本及以前,以上的写法还可以用写法上更简单的柯里化函数来写:

func completionHandler(text: String)(results: [String]?, error: NSError?) {
    self.results = results
    self.resultLabel.text = text
    self.tableView.reloadData()
}

而如今柯里化函数也不被允许了,会被编辑器要求替换为第二种方法的写法

  • 将函数选择器(selectors)的用法由原来的Selector(“doSomething”)或者大多数像我一样的直接”doSomething”改为#selector(doSomething),并且现在会在编译时检查这一写法
  • 大部分关键词现在都可以被用来作为函数的参数名
  • 现在在协议(protocol)中可以声明联合类型(Associated types)了,任何遵守协议的类或结构体可以定义具体的类型

关于Associatedtypes的解释:意思就是现在你可以通过“associatedtype”关键词在协议中声明一个(或多个)变量,这个变量的具体类型将在继承了该协议的类或结构体中来定义,来看一下官方的例子:

protocol Container {
    associatedtype ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}
//使用的时候就这样:
struct IntStack: Container {
    // original IntStack implementation
    var items = [Int]()
    mutating func push(item: Int) {
        items.append(item)
    }
    mutating func pop() -> Int {
        return items.removeLast()
    }
    // conformance to the Container protocol
    typealias ItemType = Int
    mutating func append(item: Int) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Int {
        return items[i]
    }
}

这样应该就能大概明白associated type的用法了吧,更多详细深层的用法可以去查看官方文档:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html

有关Xcode:

2.pic

Editor里只有这一条,但我相信这会让绝大多数iOS开发者非常兴奋了,对于升级为对Release notes不感兴趣的开发者,相信它们打了几个代码下去之后就会发现这令人惊喜的改变,不错,现在的Xcode自带的代码补全也加入了模糊匹配功能,而且表现很优秀,Fuzzy Autocomplete是一个非常优秀的代码补全插件,但是我在用了一段时间之后不得已从我的Xcode卸载了它,因为当应用的文件规模变大时它的性能需求也变得非常高,我最新的15”rMbp也会被弄得异常卡顿,甚至让我有了使用Windows系统的感觉。但最新版Xcode的这个自动补全功能使用起来非常顺畅,在大项目中依然不会卡顿,立刻去升级Xcode7.3吧,享受一下。

 

版权所有,转载请先联系flamelswift@gmail.com

提交ITC收到邮件提示’Invalid Swift Support’的解决方法

第二个app完工了,上传ITC的时候却无论上传几次都会直接被ITC邮件否决,提醒我’Invalid Swift Support‘,具体是这样:

The files libswiftContacts.dylib don’t match /Payload/My.app/Frameworks/libswiftContacts.dylib. Make sure the files are correct, rebuild your app, and resubmit it. Don’t apply post-processing to /Payload/My.app/Frameworks/libswiftContacts.dylib

当然之后就各种Google各种找,最后发现貌似是CocoaPods的问题

https://github.com/CocoaPods/CocoaPods/issues/4188

然后转到这个问题:

https://github.com/CocoaPods/CocoaPods/pull/4221

对于不想看英文的读者,我来总结一下:

最开始的解决方案是开启bitcode,因为bitcode较新(以上issue的时间)的缘故,大部分第三方库还没有支持bitcode,开启bitcode会使app无法build,但是到了现在我的app中引入了6个比较著名的第三方库,都已支持了bitcode,开启了bitcode之后我再上传ITC就已经build 的通过了,所以如果项目比较新,第三方库也以swift为主的可以考虑这个方法,顺便一提这个问题出现的原因就是因为引入的第三方库里面有以swift语言写的库才会出现。

以下是正确的解决方法(更新:我自己验证并没有成功):

开启Pod.project的build settings, 找到Embedded Content Contains Swift Code 由No改为Yes,同时更新CocoaPods到更新的版本(要高于0.39.0的beta5)

—————————Update————————————————————

不开启bitcode的解决方法:

更新了cocoapods之后,上述选项再改成YES直接会导致在上传ITC的时候就报错:

contains disallowed file Frameworks:xxxxxxxxx

这种时候可以这样,Pods —> Targets Supports Files —> Pods-yourappname —>  -Frameworks.sh, 找到这一条注释:

# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.

把这条注释到下一条注释之间的代码块注释掉(注意有一个 ‘}’ 不要注释掉),然后关闭Pods的Embedded Content Contains Swift Code,关闭bitcode,跑一下确认程序能正常运行,然后就可以archive上传了

Swift项目通过CocoaPods引入第三方库出现’No such module of xxx’的问题

CocoaPods是一个很方便的第三方库管理工具,但是swift似乎和它兼容的不是那么完美,尤其是引入OC库的时候,我自己经历了许多次引入了第三方库却显示”No such module of XXXX”的无法import的情况,下面说一下几个常用的解决办法

1、Build Active Architecture

进入Targets->Your project->Build settings-> Build Active Architecture Only->

将debug和release下面都改成Yes,然后build

1.pic

2、Link Binary With Libraries

如果上面一种方法不解决问题,那么尝试下如下方法:

进入Targets->Your project->Build phases->Link Binary with Libraries

看看下面是否正确添加了一个Pods.framework链接,如果没有,那么加上

W1F0V

3、Configurations

如果上面两个方法都没解决,那么尝试方法三

进入Project > Info > Configurations

J3MLi

可以看到应该是这样的,如此,把带Tests后缀的项也改成和无Tests后缀的项的样子,添加Configurations set,然后再次尝试build

如果以上三种方式都没有办法,那么就只好放弃使用CocoaPods,手动添加第三方库然后通过bridge header链接吧