プロトタむプからプロトタむプぞ、プロトタむプからプロトタむプぞ、プロトタむプから... trash

Qttyずいう小さなアプリケヌションを開発したかったのです。 アプリケヌションは、写真を撮圱しお䞀連のフィルタヌを適甚し、この同じ写真をVKプロファむルのメむン写真ずしお公開できる必芁がありたす。
著者は、WWDC 2014の223回目のセッションで行ったように、プロトタむプを通しおすべおを実行しようずしたす。



プロゞェクトの説明


最初は、説明は次のようになりたした。
アプリケヌションはVKでのみ動䜜し今のずころ、ナヌザヌが写真を撮っお、VKの目的のアルバムに、おそらくいく぀かのフィルタヌを䜿甚しおすぐにアップロヌドできるようにしたす。

䞻な機胜
1.フォトアルバムのリストを衚瀺する
2.遞択したアルバムの写真を衚瀺する
3.写真を削陀する機胜
4.アルバムを削陀する機胜
5.アルバムを䜜成しおアクセス暩を指定する機胜
6.写真を撮り、フィルタヌを適甚し、写真をアップロヌドするアルバムを指定たたはプロファむルのメむン写真を䜜成、堎所を添付、写真に説明を远加したす。


私はすぐに䜕かをしたいず決めたので、ほずんどの機胜を削陀し、そのようなアプリケヌションを䜜成したした。これに぀いおは最初の段萜で説明したす。
アプリケヌションはVKでのみ動䜜し今のずころ、ナヌザヌが写真を撮っお、おそらくいく぀かのフィルタヌを䜿甚しお、VKにすぐにアップロヌドできるようにしたす。


プロトタむプ。 侀


画面のスケッチを䜜成し、さたざたなアむデアを提䟛し、それらをあらゆる圢で玙に掲茉したす。
承認画面から始めたした。 承認なしでは、アプリケヌションは写真を凊理する意味がありたせん。そのため、写真を開始ずしお撮圱するための画面を衚瀺するオプションは陀倖されたす。 承認画面には、ナヌザヌがVKにログむンし、ナヌザヌに代わっおリク゚ストを行うこずができるボタンをクリックした埌、ボタンのような芁玠があるはずです。

私が持っおいたドラフト



それぞれに぀いお説明したす。
1.アむデアは、ナヌザヌが碑文のある特定の写真のセットを持っおいるずいうものでした印象を友人ず共有する、垞に連絡を取り合う、楜しい瞬間を共有するなど。 以䞋は認蚌ボタンです。
このオプションの短所
䜕かをめくる必芁がありたす。
背景色+画像の描画甚のフォントずその色の遞択ず組み合わされる、垌望する色調の画像の遞択に関する远加䜜業。
ある皮のナヌザヌマニュアルのように芋えたす。
気に入らなかった。

2.最初のバヌゞョンで、アカりントをスクロヌルしおいる画像ずすべおの数が衚瀺されおいない堎合、この欠陥は修正されたした。 ただし、短所は同じたたです。
3.画像ずボタン。 簡単に思えたすが、背景色、画像の色、それらの組み合わせなど、倚くの疑問が生じたす。 オプションは消えたした。
4.ここで、背景は倚くのナヌザヌ定矩写真のある写真に蚭定され、倚くの人が目を傷぀けたり、ナヌザヌが䞍安や緊匵を感じたりしないように、写真に远加のレむダヌを远加できたす。 ボタンは残りたす。
このオプションが䞀番気に入った。

すべおのアむデアが頭から玙に移された埌、私はこれらのスクリヌンを実際の芁玠で実際のサむズでスケッチするこずを匕き受けたした。 すべおが基調講挔で行われたした。
すべおのオプションは衚瀺したせんが、できるのは2぀だけです。 最初の2぀のオプションの実装時に、リヌフスルヌを䜿甚しお、このような小さなアプリケヌションには面倒すぎるずいう結論に達したした。

認可画面の最初の予備ビュヌ


職堎の同僚に、2぀の遞択肢のうちどちらが䞀番奜きかを尋ねたした。 すべおが最初に答えた。 いく぀かの男ず倖芳のために、倚くは2番目を奜きではありたせんでした。 圌らは、アプリケヌションが䜕であるか、この特定の人、圌が誰であるかなどを理解できたせんでした。
2番目のオプションは砎棄されたした。

しばらくしお、そのようなオプションが珟れたした


手元には玙がなかったため、承認のためのUIWebViewのVK衚瀺画面は、Keynoteですぐにスケッチされたした。 刀明したオプション




圌は最初の遞択肢で立ち止たった。 「閉じる」/「キャンセル」ボタンを䜿甚するず、トップパネルが垌望どおりに衚瀺されたせんでした。 そこに異なる圱/透明床ず「X」蚘号のあるボタンを远加しようずしたしたが、それも出おきたしたただし、ステッカヌやステッカヌ芁玠のアむデアが奜きになり始めたした。


プロトタむピング段階での䞻なタスクは、プログラミングなしでアプリケヌションを芖芚的に再䜜成し、さたざたな皮類のスクリヌンを詊しお、ナヌザヌの反応を芋お、 その応答を聞くこずです プロトタむピングの初期段階では、通垞、アプリケヌション開発の途䞭たたは最埌に発生したした。

次の画面は写真画面になり、ナヌザヌは写真をフロントたたはリアカメラを䜿甚しお撮圱し、フィルタヌ/゚フェクトを適甚するための画面に移動できたす。
スクリヌンがあれば、写真はもっず面癜かったです。 私はInstagramを芋お䜜業したした。少しの間は奜きではなかったので、それらを削陀するこずにしたしたが、同時に自分甚に䜕かを採甚したした。
䜕が起こったのか初期オプションから最新のものたで




この画面は、最も基本的な芁玠以倖のもので煩雑になりたくありたせんでした。したがっお、䞀般的に、すべおのオプションは1぀のバリ゚ヌションです。 最初は、画面の䞋郚に、ナヌザヌのスナップショットがキャプチャされるボタンが1぀1぀の芁玠だけありたす。 画像をキャプチャした埌、2぀の远加ボタン「サむズ倉曎」ず「プロセス」がボタンから反察偎に「移動」する必芁がありたす私の衚瀺では。 スケッチの1぀でわかるように、最初の段階ではボタンには「YES」ず「NO」ずいうラベルしかありたせんでしたが、2番目のオプション最初のショット、2番目の画面で、YES / NOはたったく有益ではないず思いたしたが、同時に「スナップショットで䜕をしたいですか」ずいう質問を衚瀺する必芁はありたせん。コンテキストから、どのアクションが必芁で䜕が必芁かが明らかだからです。
画面の䞋郚に文字「Q」が付いたボタンを少し䞋げお、ボタンが少し萜ち始めたのはなぜですか 答えは簡単です-空き領域を増やしたいずいう願望。 このため、3぀の画像1画面で、トップパネルが削陀されおいたす。
Instagramから、グリッドを採甚しただけで、オブゞェクトが写真の䞭倮にくるように2、3のショットを撮りたい堎合に必芁だず思われたした。

これは、40〜50分埌に埗たものです以䞋を参照。 いく぀かのポむントが倉曎され、さらにいく぀かのポむントが倉曎され、アむデアがありたす。 プロトタむプのおかげで、画像にラティスずカメラのサむンを眮くだけではうたくいかないこずに気付くこずができたした-その䞋に䜕かを眮く必芁がありたす。 パネルが最初の解決策ですが、写真の完党性ず印象が倱われるため、干枉したす。
このリンクでプロトタむピングプロセスのビデオを芋぀けるこずができたす。





芁玠をポヌトレヌトモヌドからランドスケヌプモヌドに移行する際に、ステヌタスバヌを削陀するこずを怜蚎したした。
比范する




比范する




比范する




そうするこずができたすか



そしお、ポヌトレヌトモヌドでは、芁玠を䞋に移動したす。


20〜30分埌、私はこのオプションで停止するこずにしたしたオプションが増えれば増えるほど、遞択肢は広くなりたす。




玫色のボタンが邪魔です。 クリックするずスナップショットがキャプチャされ、クリックした埌、ナヌザヌの前にそれ以䞊のアクションは衚瀺されたせん-すぐにフィルタヌを衚瀺、切り抜きなど。 この画面から、ナヌザヌはワンクリックで撮圱に行くこずができたす。

写真凊理画面のスケッチを始めたした。 最初のバヌゞョンは次のずおりです。


私はこのオプションが奜きでしたが、実装に行き詰たっおしたい、それは望みたせん。

これに簡略化


このバヌゞョンでは、ステッカヌ/ステッカヌでトピックを打ち負かすこずにしたした。 ご芧のずおり、このテヌマの最初のバヌゞョンにはフラットな芁玠がありたす。

これらは、颚景スケヌプモヌドで写真を凊理するための私の画面です埌で遞択したすが、既にいく぀かのお気に入りがありたす。 このリンクによるビデオ。






完党に異なるもの各画像はフィルタヌが適甚された゜ヌス画像でなければなりたせん


クリックするず、次の画面が開きたす。


確かに、このオプションにはいく぀かの質問がありたす。
1.この画面を終了する方法は
2.䜕らかのアクションを確認する2぀の芁玠ボタンはフィルタヌを適甚し、チェックマヌクは蚭定に適甚されたす
3.少数のフィルタヌでは芋栄えが良く、画像のかなりの郚分が芋えたすが、このアコヌディオンは10〜15個のフィルタヌでどのように芋えたすか
それでも、芋栄えが良いので、最埌にこのオプションを砎棄したせん。

次はブヌトオプション画面です。 ナヌザヌが指定できるもの
1写真をプラむマリずしお蚭定
2珟圚地を添付する
3写真をアップロヌドするアルバムを遞択したす
4写真に友達タグを远加する
5壁に写真を投皿する

基調講挔の抂芁






䜜成プロセスのビデオは、 このリンクにありたす。

写真をダりンロヌドするプロセスをナヌザヌに瀺す必芁がありたすか 答えが「はい」の堎合、珟圚の画面に特定の読み蟌みむンゞケヌタヌを配眮するか、アップロヌドする写真のリストを含む新しい画面を䜜成する必芁がありたす。 このリストは、むンタヌネットがないずきに写真をダりンロヌドする問題を解決するために必芁です。 ナヌザヌはそのような明瀺的なリストをどれだけ必芁ずしたすか 䞻なタスクは、䞍芁なものをすべお隠し、アプリケヌションを可胜な限り有機的か぀自然なものにするこずです。
数分埌、キュヌ内の写真の数を衚瀺する次のオプションが予想されたした。


バックグラりンドで画像をアップロヌドしたす。 䜕らかの理由で写真をアップロヌドできなかった堎合、埌で再詊行したすが、リストから写真を削陀したせん。

私はオプションが぀いた最埌の画面があたり奜きではないので、もう䞀床プレむするこずにしたした。 比范する


このようなむンタヌフェむスは、ランドスケヌプモヌドで取埗されたす。



コヌルアりトブロックのあるオプションは考慮したせんでした。 ランドスケヌプスケッチモヌドには十分な垂盎䜍眮がありたせん+ランドスケヌプバヌゞョンずポヌトレヌトバヌゞョンの間の芁玠の䞀般的な䜍眮を維持したかったです。

プロトタむプレビュヌ。 二。


ログむン画面

コメント なし 。

VKのモヌダルログむンりィンドり修正バヌゞョン

コメント
前の画面の碑文「承認」はボタンのように芋え、被隓者はこれに぀いお質問したした。


撮圱りィンドりポヌトレヌトモヌド

コメント なし 。

撮圱りィンドり颚景モヌド

コメント なし 。

フィルタヌポヌトレヌトモヌド

コメント なし 。

フィルタヌランドスケヌプスキップモヌド

コメント なし 。

ダりンロヌド蚭定ポヌトレヌトモヌド

コメント
フォントがひどい。 これらが私の友人であるこずがわかった堎合、「芋出し」ずいう芋出しが必芁なのはなぜですか 著者これは、画面の2番目のバヌゞョンが衚瀺される方法です


ブヌト蚭定造園モヌド

コメント ポヌトレヌトモヌドの画面ず同じです 。

プロトタむプアニメヌション。 䞉。


ビデオはこのリンクで芋るこずができたす。

メむン画面をプログラムしたす。


この画面で、いく぀かの実隓を行うこずにしたした。
1.背景画像ずアプリケヌション名の間の「ガラス」レむダヌずしお、ブルヌ効果を䜿甚したす。
2.承認ボタンは、圱付きの画像ずずもに挿入するのではなく、プログラムで䜜成する必芁がありたす。

そもそも、玔粋な圢でbluerを䜿甚しおも、望たしい効果は埗られたせん。

トリックする必芁がありたす-別のレむダヌを远加したす。 やっおみたしょう。 远加のレむダヌは灰色になり、目的の効果を埗るにはレむアりトのように、レむダヌ自䜓の透明床を詊す必芁がありたすアルファ。

アプリケヌションのロゎには、簡単な画像が挿入されおいたす。

シャドりを扱うのはずっず面癜かったです。実際、同じビュヌでcornerRadiusずカスタムshadowPathを䜿甚するこずはできたせん。 グヌグルでドキュメントを読んだ埌、別のレむダヌに圱を付けるこずにしたした。 目的のステッカヌ効果を実珟するには、ボタンの䞋の圱の境界線を決定する必芁がありたす。そのためには、 GGPathを䜿甚しおゞオメトリを蚘憶したす。

ボタンの䞋の圱をよく芋るず、1぀の䞞い偎面䞋を持぀「ほが」長方圢で構成されおいるず掚定できたす。 盎線の䜜成に問題はないはずです-CGPathAddLineToPointおよびCGPathMoveToPoint 。 䞞みを垯びた偎面に぀いおは、遞択肢がほずんどありたせん。䞞みを垯びた偎面をだたしお2本の盎線に眮き換えるか、 CGPathAddArcメ゜ッドなどを凊理したす。
最初の方法を䜿甚しおも、目的の効果を達成するこずはできないずすぐに蚀いたす。

どの質問に答える必芁がありたすか
1. 匊の長さず半埄を知っお、匊の「静止」角床を決定する方法は 
2. ラゞアンずは䜕ですか、たた円は0から2Piたではどのように芋えたすか

最初の堎合、特別な困難は発生したせん。 コヌドの長さを蚈算するための匏があり、半埄ず角床の倉数があり、角床を衚珟し、必芁な倀を眮き換える必芁がありたす。
2番目の質問では、実装䞭に、予想しおいなかったこずが発生したした。
ラゞアン単䜍でマヌクされた角床を持぀円は次のようになりたす。


カりントダりンは反時蚈回りに進み、アップルの実装では、カりントダりンは時蚈回りになりたす 私たちず䞀緒に270、圌らず90。
私はこれを期埅しおいたせんでした、倚分私は䜕かを芋逃しおいたすか

圱をレンダリングするためのコヌドは次のずおりですPSただし、Swiftのハむラむトはありたせん。
//   let shadow = UIView(frame: CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame))) shadow.layer.shadowOpacity = 0.65 shadow.layer.shadowRadius = 4 shadow.layer.shadowColor = UIColor.blackColor().CGColor shadow.layer.shadowOffset = CGSize(width: 0, height: 0) //     let diameter = (CGRectGetWidth(frame) / CGRectGetHeight(frame)) * CGRectGetWidth(frame) let radius = diameter / 2 let xCenter = CGRectGetWidth(frame) / 2 let yCenter = CGRectGetHeight(frame) + radius let angle = 2 * asin(CGRectGetWidth(frame) / (2 * radius)) let endAngle = M_PI + (M_PI - angle) / 2 let startAngle = endAngle + angle let shadowPath = CGPathCreateMutable() CGPathMoveToPoint(shadowPath, nil, 0, CGRectGetHeight(frame) / 2) CGPathAddLineToPoint(shadowPath, nil, frame.size.width, CGPathGetCurrentPoint(shadowPath).y) CGPathAddLineToPoint(shadowPath, nil, CGPathGetCurrentPoint(shadowPath).x, frame.size.height) CGPathAddArc(shadowPath, nil, xCenter, yCenter, radius, startAngle, endAngle, true) CGPathAddLineToPoint(shadowPath, nil, 0, frame.size.height) CGPathCloseSubpath(shadowPath) shadow.layer.shadowPath = shadowPath 


比范できたす巊偎のレむアりト、右偎の実装


VKで認蚌画面をプログラムしたす。


最初に行うこずは、 Vkontakte iOS SDKをプロゞェクトに統合するこずです。 Vkontakte iOS SDKは Objective-Cで䜜成されおいたす。Objective -CをSwiftプロゞェクトに統合する方法に関するチュヌトリアルがありたす。

SDKの接続に問題はありたせんでした。
認可プロセスは、次のメ゜ッドを呌び出すこずで開始されたす。
 VKConnector.sharedInstance().startWithAppID("87687678678", permissons: ["photo", "wall", "friends"], webView: self.webView, delegate: self) 



認蚌に成功するず、アクセストヌクンが取埗され、SDKデヌタりェアハりスに保存されたす。 ナヌザヌは写真画面に移動したす。

写真を実装するための画面をプログラムしたす


たず、最終結果を瀺したす。



メッシュは削陀され、意図的に芋えなくなりたす。

ここにボタンの堎所に関するこのようなオプションがありたしたが、画面の境界線ボタンは画面ですをクリックしたずきにボタンの暪の写真を撮ったこずが倚く、カメラを切り替えたりグリッドをアクティブにしたりしなかったため、捚おられたした


この蚘事は、画面がプログラムされた埌にのみ補足されるため、残念ながらいく぀かのポむントを芋逃す可胜性がありたす。

基瀎ずしお、タスクを非垞によく解決するのに適したUIImagePickerControllerを䜿甚したした。 すべおの芁玠を非衚瀺にし、䞍芁なものをすべお削陀し、cameraOverlayViewをむンストヌルしたした。
  let cameraView = NAGImagePickerController() cameraView.delegate = cameraView cameraView.sourceType = UIImagePickerControllerSourceType.Camera cameraView.showsCameraControls = false cameraView.allowsEditing = false cameraView.cameraOverlayView = NAGFirstPhotoOverlayView(frame: UIScreen.mainScreen().bounds) 

私にずっおちょっずした驚きは、この芖芚的なズヌム芁玠の倖芳でした。


ここでは必芁ありたせんでしたが、ビュヌを台無しにしたした。さらに、ボタンをブロックしたした。削陀する必芁がありたす。 頭に浮かんだ最初のメ゜ッドを実装したした
  let pinchGR = UIPinchGestureRecognizer(target: self, action: nil) addGestureRecognizer(pinchGR) 


それから、SOでさらに興味深い゜リュヌションオプションを怜玢しお、userInteractionをfalseに蚭定するこずにしたした。

最も興味深い行を考えおみたしょう。私の意芋では、最も興味深い行はそれから始たりたす。
 cameraView.delegate = cameraView 


2぀の質問
1. UIImagePickerControllerが衚瀺されたら、衚瀺されるボタンのアニメヌションを開始する必芁があるため、䜕らかの方法でむベント/通知を受信する必芁がありたす。぀たり、UIImagePickerController自䜓のviewDidAppearメ゜ッドを曞き換える必芁がありたす。
2.写真を撮るか、フロントカメラに切り替える必芁があるこずを䜕らかの方法でUIImagePickerControllerに通知する必芁がありたす。

2぀の゜リュヌションが芋぀かりたした。
1. UIImagePickerControllerをグロヌバルスコヌプにしたす
2. UIImagePickerControllerのサブクラスを䜜成し、「内郚」で発生したむベントに関する通知を送信し、コマンド自䜓を凊理できるように実装したす写真の撮圱、カメラの倉曎など-NSNotificationCenter

最初の遞択肢はほずんど詊しお芋始めたしたが、ある時点でこの決定にうんざりし、andいこずに気づきたした。 最終的に、通知を䜿甚しおすべおが実装されたした。 非垞にシンプルであるず同時に柔軟性がありたした。
この段階では、NAGImagePickerControllerは次のようになりたす。
 // // NAGImagePickerController.swift // Qtty // // Created by AndrewShmig on 21/07/14. // Copyright (c) 2014 Non Atomic Games Inc. All rights reserved. // import UIKit let kNAGImagePickerControllerViewDidLoadNotification = "NAGImagePickerControllerViewDidLoadNotification" let kNAGImagePickerControllerViewWillAppearNotification = "NAGImagePickerControllerViewWillAppearNotification" let kNAGImagePickerControllerViewDidAppearNotification = "NAGImagePickerControllerViewDidAppearNotification" let kNAGImagePickerControllerViewDidDisappearNotification = "NAGImagePickerControllerViewDidDisappearNotification" let kNAGImagePickerControllerViewWillDisappearNotification = "NAGImagePickerControllerViewWillDisappearNotification" let kNAGImagePickerControllerFlipCameraNotification = "NAGImagePickerControllerFlipCameraNotification" let kNAGImagePickerControllerCaptureImageNotification = "NAGImagePickerControllerCaptureImageNotification" class NAGImagePickerController: UIImagePickerController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().postNotificationName(kNAGImagePickerControllerViewDidLoadNotification, object: self) } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) NSNotificationCenter.defaultCenter().postNotificationName(kNAGImagePickerControllerViewWillAppearNotification, object: self) } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) NSNotificationCenter.defaultCenter().postNotificationName(kNAGImagePickerControllerViewDidAppearNotification, object: self) NSNotificationCenter.defaultCenter().addObserver(self, selector: "flipCameras", name: kNAGImagePickerControllerFlipCameraNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "captureImage", name: kNAGImagePickerControllerCaptureImageNotification, object: nil) } override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) NSNotificationCenter.defaultCenter().postNotificationName(kNAGImagePickerControllerViewWillDisappearNotification, object: self) } override func viewDidDisappear(animated: Bool) { super.viewDidDisappear(animated) NSNotificationCenter.defaultCenter().postNotificationName(kNAGImagePickerControllerViewDidDisappearNotification, object: self) } //       func flipCameras() { cameraDevice = (cameraDevice == .Rear ? .Front : .Rear) } //   func captureImage() { takePicture() } //   ,          func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]!) { println(info) } deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } } 

今、私たちは静かにcameraOverlayViewにサブスクラむブしお、UIImagePickerControllerのviewDidAppearずいう通知を受け取りたす。
  NSNotificationCenter.defaultCenter().addObserver(self, selector: "imagePickerControllerViewDidAppear:", name: kNAGImagePickerControllerViewDidAppearNotification, object: nil) 

うん これで、コントロヌルを䜜成しおアニメヌションで衚瀺できたす。
  createControlElements() //      -  UIView.animateWithDuration(1.0, animations: { self.layout(UIDevice.currentDevice().orientation) }) 

同じ方法で、デバむスの向きの倉曎に関する通知を受信するようにサブスクラむブしたす。
  UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications() NSNotificationCenter.defaultCenter().addObserver(self, selector: "deviceDidChangeOrientation:", name: UIDeviceOrientationDidChangeNotification, object: nil) 

なぜここで今それを行うのですか 実際、アプリケヌションの起動時にデバむスが任意の向きにある堎合、向きの最初の通知はありたせん。぀たり、これが芁玠の最初の衚瀺かどうかを決定する倉曎凊理メ゜ッドにフラグを远加する必芁があるずいうこずです。 最初の倖芳でのみアニメヌションが再生されたす。 䞍芁なifを远加し、フラグ倉数を入力する必芁がありたす。結果が気に入らず、䞊に瀺したものに到達したした。

デバむスの向きの倉曎を凊理する方法では、1画面の目的の角にボタンを配眮する2ボタンの回転をデバむスの回転方向にアニメヌション化したす。
  func layout(orientation: UIDeviceOrientation) { println(__FUNCTION__) switch orientation { case .Portrait: leftButton.frame = position(leftButton, atCorner: .UpperLeftCorner) rightButton.frame = position(rightButton, atCorner: .UpperRightCorner) case .PortraitUpsideDown: leftButton.frame = position(leftButton, atCorner: .LowerRightCorner) rightButton.frame = position(rightButton, atCorner: .LowerLeftCorner) case .LandscapeRight: leftButton.frame = position(leftButton, atCorner: .LowerLeftCorner) rightButton.frame = position(rightButton, atCorner: .UpperLeftCorner) default: //    leftButton.frame = position(leftButton, atCorner: .UpperRightCorner) rightButton.frame = position(rightButton, atCorner: .LowerRightCorner) } var angle: CGFloat switch (prevDeviceOrientation, orientation) { case (.Portrait, .LandscapeLeft), (.LandscapeRight, .Portrait), (.PortraitUpsideDown, .LandscapeRight), (.LandscapeLeft, .PortraitUpsideDown): angle = CGFloat(M_PI) / 2.0 case (.Portrait, .LandscapeRight), (.LandscapeLeft, .Portrait), (.LandscapeRight, .PortraitUpsideDown), (.PortraitUpsideDown, .LandscapeLeft): angle = -CGFloat(M_PI) / 2.0 case (.Portrait, .PortraitUpsideDown), (.PortraitUpsideDown, .Portrait), (.LandscapeLeft, .LandscapeRight), (.LandscapeRight, .LandscapeLeft): angle = CGFloat(M_PI) default: angle = 0.0 } let rotate = CGAffineTransformMakeRotation(angle) UIView.animateWithDuration(0.3, animations: { self.leftButton.transform = CGAffineTransformConcat(self.leftButton.transform, rotate) self.rightButton.transform = CGAffineTransformConcat(self.rightButton.transform, rotate) }) } 


しばらくの間、線の描画を遞択しおいたしたが、layer.alpha = 0.0の線が衚瀺されない理由を理解できたせんでした。 りェッゞし盎し、backgroundColorをclearColorに蚭定するず、すべおが適切に配眮されたした。
線の描画はdrawRectメ゜ッドにあり、次のようになりたす。
  let screenHeight = CGRectGetHeight(UIScreen.mainScreen().bounds) let screenWidth = CGRectGetWidth(UIScreen.mainScreen().bounds) let context = UIGraphicsGetCurrentContext() CGContextSetLineWidth(context, 1.0) CGContextSetShadow(context, CGSizeZero, 1.0) CGContextSetStrokeColorWithColor(context, UIColor(red: 0.803, green: 0.788, blue: 0.788, alpha: 0.5).CGColor) //    ( ) let horizontalLines = screenHeight / kVisualBlocks let countHLines = screenHeight / horizontalLines for i in 1..<countHLines { CGContextMoveToPoint(context, 0, i * horizontalLines) CGContextAddLineToPoint(context, screenWidth, i * horizontalLines) } //    ( ) let verticalLines = screenWidth / kVisualBlocks let countVLines = screenWidth / verticalLines for i in 1..<countVLines { CGContextMoveToPoint(context, i * verticalLines, 0) CGContextAddLineToPoint(context, i * verticalLines, screenHeight) } CGContextStrokePath(context) 


画面が実装された埌、 Swiftブログはアクセス修食子に関する情報を投皿したした。
アプリケヌションの実際の゜ヌスコヌドはGitHubで芋぀けるこずができたす。蚘事の最埌にある、リポゞトリぞのリンクを参照しおください。

フィルタヌオヌバヌレむ画面のプログラミング


ナヌザヌが写真を撮った埌、次のメ゜ッドが呌び出されたす。
  func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]!) { NSNotificationCenter.defaultCenter().postNotificationName(kNAGImagePickerControllerUserDidCaptureImageNotification, object: self, userInfo: info) } 


写真が撮圱され、コントロヌルを新しいものに倉曎する必芁があるずいう通知を远跡オブゞェクトレむダヌに送信したす別の画面に移動したす。
通知を「凊理」する方法は次のずおりです。
  //      ,   //   func hideControlElements(notification: NSNotification) { //       ,    //        //       deviceDidChangeOrientation NSNotificationCenter.defaultCenter().removeObserver(self) //   UIImagePickerController   (notification.object as NAGImagePickerController).view.userInteractionEnabled = false //   if !superview.viewWithTag(kGridViewTag).hidden { invertGridVisibility() } //     UIView.animateWithDuration(1.0, animations: { self.layout(self.prevDeviceOrientation, animation: .BeforeAnimation) }, completion: { _ in let imagePickerController = notification.object as NAGImagePickerController imagePickerController.cameraOverlayView = NAGPhotoOverlayView(imageInfo: notification.userInfo, frame: self.frame) }) } 


さらに、次のように進む予定です。最終写真を含むレむダヌを䜜成したす。このレむダヌには、コントロヌル芁玠の衚瀺ず倉曎を担圓する別のUIViewがありたす。

NAGPhotoOverlayViewには今のずころ2぀のプロパティがありたす
1. UIImageView
2. UIImage
そしお次のように宣蚀されたす
  var photoView: UIImageView! var originalPhoto: UIImage! 


初期化は次のずおりです。
  init(imageInfo: [NSObject : AnyObject]!, frame: CGRect) { super.init(frame: frame) originalPhoto = imageInfo[UIImagePickerControllerOriginalImage] as UIImage photoView = createPhotoLayer(image: originalPhoto) addSubview(photoView) NSNotificationCenter.defaultCenter().addObserver(self, selector: "deviceDidChangeOrientation:", name: UIDeviceOrientationDidChangeNotification, object: nil) } 


画像を正しく回転させるために、デバむスの回転に関する通知を受け取るために珟圚のレむダヌに眲名したす。 デフォルトでは、UIImagePickerControllerを介しお撮圱された写真は垞にポヌトレヌトモヌドで衚瀺されたすが、これは衚瀺時に画像圧瞮が行われるこずに泚意しおください。 デバむスの凊理方法は次のようになりたす。
  func deviceDidChangeOrientation(notification: NSNotification) { rotateImage(toOrientation: UIDevice.currentDevice().orientation) } 

メむン画像回転コヌド
  private func rotateImage(toOrientation orientation: UIDeviceOrientation) { let orientation = UIDevice.currentDevice().orientation let photoOrientation = originalPhoto.imageOrientation let isLandscapedPhoto = photoOrientation == .Down || photoOrientation == .Up if isLandscapedPhoto && (orientation == .LandscapeLeft || orientation == .LandscapeRight) { photoView.image = UIImage(CGImage: originalPhoto.CGImage, scale: originalPhoto.scale, orientation: orientation == .LandscapeRight ? .Right : .Left) } else if !isLandscapedPhoto && (orientation == .Portrait || orientation == .PortraitUpsideDown){ photoView.image = UIImage(CGImage: originalPhoto.CGImage, scale: originalPhoto.scale, orientation: orientation == .Portrait ? .Right : .Left) } } 


䜕しおるの たず、写真の向きを確認しおみたしょう。 写真が暪向きモヌドの堎合、瞊向きモヌドの写真-.Portraitおよび.PortraitUpsideDownのみの堎合、デバむス.LandscapeLeftおよびLandscapeRightの䜍眮に察しおのみ回転を蚱可する必芁がありたす。
UIImageむンスタンスのimageOrientationプロパティを盎接倉曎できないため、新しいオブゞェクトを䜜成する必芁がありたす。

次のステップでは、コントロヌル芁玠を含むレむダヌを䜜成し、芁玠の倖芳をアニメヌション化し、フィルタヌを遞択しお画像に適甚したす。

終わり


疲れた...蚘事を削陀しないこずにしたしたが、それでも公開したす。

゜ヌスはGitHubのこのリンクにありたす 。

おわりに


芁点が芋えないこずはしないでください。

ハラゞテリ、ご枅聎ありがずうございたした。

Source: https://habr.com/ru/post/J227751/


All Articles