30DaysofSwift繼續(xù)學(xué)習(xí)中暑塑,目測(cè)下部分更有趣些处坪,小白筆記繼續(xù)中···
另外作者在簡(jiǎn)書(shū)上也有記錄,自學(xué) iOS - 三十天三十個(gè) Swift 項(xiàng)目
十六费坊、上邊欄目錄菜單的實(shí)現(xiàn) (day16)
在此之前我們可以去拜讀一下貓神的iOS7中的ViewController切換,了解下
-
UIViewControllerTransitioningDelegate
: 切換中應(yīng)該發(fā)生什么 -
UIViewControllerAnimatedTransitioning
: 詢(xún)問(wèn)是否需要使用自定義的切換效果
另外詳細(xì)看看這個(gè)View Controller切換效果倒槐。
以及調(diào)用snapshotViewAfterScreenUpdates
創(chuàng)建一個(gè)復(fù)合視圖的快照,就是截屏附井。
另外要注意一下 Storyboard unwind segues使用小結(jié),這樣也不失為不使用 delegate 模式傳遞回調(diào)數(shù)據(jù)的好方法讨越。
這個(gè)Demo中可以深究的地方有蠻多的,有空再單獨(dú)做筆記的
十七永毅、模仿微博點(diǎn)擊Tab中編輯后彈出的效果 (day17)
再次學(xué)習(xí)ViewController的動(dòng)畫(huà)切換把跨,對(duì)Transitioning
更加了解···
private var presenting = false
//MARK:-UIViewControllerContextTransitioning
// 完成容器轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的主要方法,我們對(duì)于切換時(shí)的UIView的設(shè)置和動(dòng)畫(huà)都在這個(gè)方法中完成
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
}
// 系統(tǒng)給出一個(gè)切換上下文沼死,我們根據(jù)上下文環(huán)境返回這個(gè)切換所需要的花費(fèi)時(shí)間
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.5
}
//MARK:- UIViewControllerTransitioningDelegate
// 呈現(xiàn)VC時(shí)CallBack的方法
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = true
return self
}
//解散VC時(shí)CallBack的方法
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = false
return self
}
在animateTransition
中的實(shí)現(xiàn)
1着逐、我們需要得到參與切換的兩個(gè)ViewController的信息,使用context的方法拿到它們的參照意蛀;
2耸别、對(duì)于要呈現(xiàn)的VC,我們希望它什么樣的方式入場(chǎng)浸间,Transform
的設(shè)置太雨;
3、將view添加到containerView中魁蒜;
4囊扳、開(kāi)始動(dòng)畫(huà)。這里的動(dòng)畫(huà)時(shí)間長(zhǎng)度和切換時(shí)間長(zhǎng)度一致兜看。
5锥咸、在動(dòng)畫(huà)結(jié)束后我們必須向context報(bào)告VC切換完成,是否成功细移。系統(tǒng)在接收到這個(gè)消息后搏予,將對(duì)VC狀態(tài)進(jìn)行維護(hù)
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
// 初始化
let container = transitionContext.containerView()
// 得到參與切換的兩個(gè)ViewController的信息,使用context的方法拿到它們的參照
let screens : (from:UIViewController, to:UIViewController) = (transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!, transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!)
let menuViewController = !self.presenting ? screens.from as! MenuViewController : screens.to as! MenuViewController
let bottomViewController = !self.presenting ? screens.to as UIViewController : screens.from as UIViewController
let menuView = menuViewController.view
let bottomView = bottomViewController.view
//對(duì)于要呈現(xiàn)的VC,我們希望它以什么樣的方式入場(chǎng)
if (self.presenting) {
// 初始化需要建立好的 Transform
self.offStageMenuController(menuViewController)
}
//將view添加到containerView中
container!.addSubview(bottomView)
container!.addSubview(menuView)
// 后面是開(kāi)始動(dòng)畫(huà)啦
let duration = self.transitionDuration(transitionContext)
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: [], animations: {
if (self.presenting){
self.onStageMenuController(menuViewController)
} else {
self.offStageMenuController(menuViewController)
}
}, completion: { finished in
// 在動(dòng)畫(huà)結(jié)束后我們必須向context報(bào)告VC切換完成,是否成功弧轧。系統(tǒng)在接收到這個(gè)消息后雪侥,將對(duì)VC狀態(tài)進(jìn)行維護(hù)
transitionContext.completeTransition(true)
UIApplication.sharedApplication().keyWindow!.addSubview(screens.to.view)
})
}
十八、鍵盤(pán)的彈出跟隨InputAccessoryView(day18)
首先順便歸納下精绎,讓鍵盤(pán)下移的常用三種方法
// 方法一速缨、UIApplication.sharedApplication().keyWindow
@IBAction func tapDownAction(sender: AnyObject) {
UIApplication.sharedApplication().keyWindow?.endEditing(true)
}
// 方法二、textField的resignFirstResponder方法
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
// 方法三代乃、任意點(diǎn)擊屏幕
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
而此Demo主要的是通知的運(yùn)用和動(dòng)畫(huà)小彈出的熟練了,注意userInfo
字典的key
let keyBoardBounds = (userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
let duration = (userInfo![UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
// 這個(gè)options的轉(zhuǎn)換旬牲,很有意思
let options = UIViewAnimationOptions(rawValue: UInt((userInfo![UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).integerValue << 16))
最要注意UIKeyboardAnimationCurveUserInfoKey
轉(zhuǎn)換成 UIViewAnimationOptions
的過(guò)程。
十九、加閃爍字體的刷新效果 (day19)
首先了解下 UIViewAnimationOptions
動(dòng)畫(huà)速度控制的幾個(gè)參數(shù)原茅;
CurveEaseInOut: UIViewAnimationOptions // 動(dòng)畫(huà)先緩慢吭历,然后逐漸加速
CurveEaseIn: UIViewAnimationOptions // 動(dòng)畫(huà)逐漸變慢
CurveEaseOut: UIViewAnimationOptions // 動(dòng)畫(huà)逐漸加速
CurveLinear: UIViewAnimationOptions // 動(dòng)畫(huà)勻速執(zhí)行
對(duì)CGAffineTransform
進(jìn)一步了解
總得來(lái)說(shuō),這個(gè)類(lèi)中包含3張不同類(lèi)型擂橘,分別使用如下3個(gè)方法創(chuàng)建數(shù)值晌区;
1.CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)(平移:設(shè)置平移量)
2.CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)(縮放:設(shè)置縮放比例)僅通過(guò)設(shè)置縮放比例就可實(shí)現(xiàn)視圖撲面而來(lái)和縮進(jìn)頻幕的效果。
3.CGAffineTransformMakeRotation(CGFloat angle)(旋轉(zhuǎn):設(shè)置旋轉(zhuǎn)角度)
以上3個(gè)都是針對(duì)視圖的原定最初位置的中心點(diǎn)為起始參照進(jìn)行相應(yīng)操作的贝室,在操作結(jié)束之后可對(duì)設(shè)置量進(jìn)行還原:
view.transform=CGAffineTransformIdentity;
二十契讲、CollectionView中點(diǎn)擊Cell直接放大Cell (day20)
首先先說(shuō)一個(gè)問(wèn)題,之前我看作者也是這樣的滑频,就是我們?cè)谠O(shè)置Item的時(shí)候直接將它的size 設(shè)置死了捡偏,是不適配的,所以此時(shí)是否還是要用呢峡迷,或者換成UITableView其實(shí)也OK 的银伟,畢竟一行只有一個(gè)item。
當(dāng)然先看看核心代碼
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// 獲取當(dāng)前Cell
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! TestCollectionViewCell
// 并把到放在最前面
cell.superview?.bringSubviewToFront(cell)
// 動(dòng)畫(huà)效果
UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [], animations: { () -> Void in
cell.frame = self.collectionView.frame
self.collectionView.scrollEnabled = false
cell.backButton.hidden = false
cell.backButton.addTarget(self, action: Selector("backButtonDidTouch"), forControlEvents: UIControlEvents.TouchUpInside)
}, completion: nil)
}
func backButtonDidTouch() {
self.collectionView?.scrollEnabled = true
//選中的cell
let indexPath = self.collectionView!.indexPathsForSelectedItems()
//刷新當(dāng)前 index,恢復(fù)成原來(lái)的位置
self.collectionView?.reloadItemsAtIndexPaths(indexPath!)
}
二十一绘搞、cell左邊滑動(dòng)刪除或其他 (day21)
注意UITableViewRowAction
創(chuàng)建刪除按鈕和 UIActivityViewController
在應(yīng)用里為分享和操作數(shù)據(jù)提供了一個(gè)統(tǒng)一的服務(wù)接口
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .Normal, title: "Delete"){
(action: UITableViewRowAction!, indexPath: NSIndexPath) -> Void in
// 刪除某一行
self.dataArray.removeAtIndex(indexPath.row)
self.tableView.reloadData()
}
delete.backgroundColor = UIColor.redColor()
let share = UITableViewRowAction(style: .Normal, title: "Share") { (action: UITableViewRowAction!, indexPath: NSIndexPath) -> Void in
// 分享某個(gè)東西
let firstActivityItem = self.dataArray[indexPath.row]
let activityViewController = UIActivityViewController(activityItems: [firstActivityItem as NSString], applicationActivities: nil)
self.presentViewController(activityViewController, animated: true, completion: nil)
}
share.backgroundColor = UIColor.greenColor()
return [delete, share]
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
// 確保上面那個(gè)方法生效彤避,可以什么都不寫(xiě)
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}
二十二、3D Touch 的使用(day22)
可以去看這篇文章iOS9系列專(zhuān)題一——3D Touch夯辖,雖說(shuō)模擬器也可以通過(guò)安裝插件嘗試琉预,但是還是想著后期真機(jī)嘗試,那感覺(jué)偷懶的有價(jià)值蒿褂,??圆米。
發(fā)現(xiàn)這篇也不錯(cuò)iOS9-by-Tutorials-學(xué)習(xí)筆記九:3D-Touch/
二十三、側(cè)滑效果的實(shí)現(xiàn) (day23)
Demo基于SWRevealViewController這個(gè)來(lái)實(shí)現(xiàn)的啄栓。
初次使用的時(shí)候娄帖,如果是用storyBoard的需要注意
NSString * const SWSegueRearIdentifier = @"sw_rear";
NSString * const SWSegueFrontIdentifier = @"sw_front";
NSString * const SWSegueRightIdentifier = @"sw_right";
也就是默認(rèn)跳轉(zhuǎn)的幾個(gè)segue
的標(biāo)識(shí)。
二十四昙楚、滑動(dòng)圖片時(shí)循序漸進(jìn)的出現(xiàn)近速,瀑布流中一個(gè)很好效果(day24)
逐漸變化是用透明度的,item的size是用FMMosaicLayout自適應(yīng)的堪旧,處理更方便削葱。
透明度變化的效果:
let randomBlue = CGFloat(drand48())
let randomRed = CGFloat(drand48())
let randomGreen = CGFloat(drand48())
cell.backgroundColor = UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0)
cell.alpha = 0
let cellDelay = UInt64((arc4random() % 600 ) / 1000 )
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(cellDelay * NSEC_PER_SEC )), dispatch_get_main_queue(), ({ () -> Void in
UIView.animateWithDuration(0.8, animations: ({
cell.alpha = 1.0
}))
}))
二十五、常用的動(dòng)畫(huà)效果展示(day25)
Position
,Opacity
, Scale
,Color
,Rotation
其實(shí)也是對(duì)這個(gè)方法的熟練淳梦,以及CGAffineTransform
的熟悉佩耳。
二十六、通過(guò)UIAlertController增加UITableViewCell和刪除 (day26)
也是對(duì)UIAlertController
的熟悉下
let alert = UIAlertController(title: "AddNew", message: "", preferredStyle: UIAlertControllerStyle.Alert)
alert.addTextFieldWithConfigurationHandler({
(textField) in
textField.placeholder = "add content data"
})
let alertOK = UIAlertAction(title: "OK", style: .Default, handler:({
(action: UIAlertAction) -> Void in
let inputField = (alert.textFields?.first)! as UITextField
self.dataArray .append(inputField.text!)
self.tableView.reloadData()
}))
let alertCancel = UIAlertAction(title: "Cancel", style: .Cancel, handler:({
(action: UIAlertAction) -> Void in
print("cacel Handle")
}))
alert.addAction(alertOK)
alert.addAction(alertCancel)
self.presentViewController(alert, animated: true, completion: nil)
二十七谭跨、TabBar
storyBoard 制作tabBar,并且回顧了之前那個(gè)動(dòng)畫(huà)讓cell走動(dòng),以及幾個(gè)動(dòng)畫(huà)效果的實(shí)現(xiàn),算是對(duì)前幾次的一個(gè)回顧吧螃宙,綜合練習(xí)題蛮瞄。
二十八、通過(guò)外部的搜索谆扎,直接進(jìn)入APP里面
也就是CoreSpotlight
框架的使用挂捅,這個(gè)框架可以為iOS的搜索提供一些App內(nèi)部的數(shù)據(jù),能夠使我們?cè)趇Phone上下拉出現(xiàn)得搜索框中堂湖,搜索我們使用的App中的內(nèi)容闲先。
了解一下Core Spotlight Framework搜索App的內(nèi)容
二十九、模仿QQ選擇圖片无蜂,直接在界面瀏覽相冊(cè)
作者用了ImagePickerSheetController,確實(shí)方便簡(jiǎn)單伺糠,但是目前github 上貌似沒(méi)有更新, 暫時(shí)不怎么好用,可以直接用作者提供的斥季。
let controller = ImagePickerSheetController()
controller.addAction(ImageAction(title: NSLocalizedString("Take Photo or Video", comment: "Action Title"), secondaryTitle: NSLocalizedString("Use this one", comment: "Action Title"), handler: { (_) -> () in
}, secondaryHandler: { (action, numberOfPhotos) -> () in
controller.getSelectedImagesWithCompletion({ (images) -> Void in
self.profileImage = images[0]
self.userProfileImageView.image = self.profileImage
})
}))
controller.addAction(ImageAction(title: NSLocalizedString("Cancel", comment: "Action Title"), style: .Cancel, handler: nil, secondaryHandler: nil))
presentViewController(controller, animated: true, completion: nil)
最近發(fā)現(xiàn)了一個(gè)新的HySideScrollingImagePicker,對(duì)于選擇圖片的做的也不錯(cuò)训桶,可以看看。
三十酣倾、通過(guò)搜索名字展現(xiàn)圖片
首先是網(wǎng)絡(luò)請(qǐng)求舵揭,它這邊尋找的圖像是需要翻墻的,其次對(duì)人臉的識(shí)別處理可以了解下躁锡。
#使用Core Image來(lái)檢測(cè)眨眼以及微笑
// 獲得圖片
let faceImage = imageView.image
// 初始化 CIDetector
let detector = CIDetector(ofType: CIDetectorTypeFace, context: CIContext(options: nil), options: [CIDetectorAccuracy:CIDetectorAccuracyHigh])
// 轉(zhuǎn)化CIImage
let ciImage = CIImage(CGImage: faceImage!.CGImage!)
// 識(shí)別圖片
let features = detector.featuresInImage(ciImage)
if features.count > 0 {
// 去獲得特征
var face:CIFaceFeature!
for rect in features
{
face = rect as! CIFaceFeature
}
// 檢查笑臉
if (face.hasSmile)
{
print("笑了");
}
else
{
print("沒(méi)有笑");
}
// 當(dāng)然眼睛的位置和嘴巴的位置也可以找到的
/*
public var bounds: CGRect { get }
public var leftEyePosition: CGPoint { get }
public var rightEyePosition: CGPoint { get }
public var mouthPosition: CGPoint { get }
*/
}
總的說(shuō)來(lái)午绳,通過(guò)這些Demo重寫(xiě),讓我基本對(duì)Swift以及iOS好多知識(shí)點(diǎn)有了進(jìn)一步的認(rèn)識(shí)映之,當(dāng)然有好多方面的也沒(méi)有深入拦焚,同時(shí)這邊最大的感覺(jué)應(yīng)該是對(duì)動(dòng)畫(huà)效果沒(méi)有那么畏懼了,不會(huì)像以前覺(jué)的動(dòng)畫(huà)效果感覺(jué)很難的似的惕医。當(dāng)然里面Demo中有一些編碼習(xí)慣是可以有選擇的耕漱,但是想想作者并不是專(zhuān)業(yè)的iOS開(kāi)發(fā)人員,本人還是相當(dāng)汗顏的抬伺,學(xué)習(xí)螟够!學(xué)習(xí)啊峡钓!