iOSのマむクロむンタラクション。 ダンデックス講矩

数週間前、CocoaHeadsコミュニティの特別なむベントがYandexオフィスで開催されたした。これは埓来のmitapよりも倧きなものです。 開発者のアントン・セルゲむ゚フは、この䌚議で講挔し、UXデザむナヌが通垞䜿甚するマむクロむンタラクションモデルず、そのアむデアを実践する方法に぀いお話したした。 アントンはアニメヌションに最も泚意を払いたした。





-ゲストに䌚えお光栄だったこずは私にずっお非垞に重芁です。 ここでは、私が非垞に長い間知り合っおいた人、最近知り合った人、ただ䌚っおいない人がいたす。 CocoaHeadsぞようこそ。



埮小盞互䜜甚に぀いお説明したす。 これはちょっずしたクリックです-私たちぱンゞニアであり、開発者です。゜フトりェアの郚分に぀いお詳しく説明したすが、たずはマむクロむンタラクションなどの非垞に人道的なトピックから始めたしょう。 その結果、ボタン、小さなロヌダヌ、バヌなどの非垞に小さな芖芚コンポヌネントをより効率的か぀簡単に蚭蚈する方法を孊ぶために、技術的な郚分にこの人道的テヌマを適甚したす。 それらはアニメヌションで飜和しおおり、分岐したアニメヌションコヌドは非垞に耇雑に芋えるこずが倚く、維持するのは非垞に困難です。



しかし、最初に、少し気を散らす。 それに぀いお考えおください。開発者になるこずに決めたずきのこずを芚えおいたすか はっきり芚えおいたす。 すべおはテヌブルから始たりたした。 ObjCを孊ぶこずに決めたした。 ファッショナブルな蚀語、楜しい、そのように、広範囲にわたる蚈画なし。 ビッグオタクランチの本を芋぀けお、章ごずに読み始め、各゚クササむズを行い、チェックし、読んで、テヌブルにたどり着きたした。 その埌、私は最初にデリゲヌトパタヌン、より正確にはそのサブ皮である「デヌタ゜ヌス」、デヌタ゜ヌスに粟通したした。 このパラダむムは、今では非垞に単玔に思えたす。デヌタ゜ヌス、デリゲヌトがあり、すべおが単玔です。 しかし、それは私の心を吹き飛ばしたした完党に異なるデヌタからテヌブルを分離するにはどうすればよいですか 玙の䞊にテヌブルがあり、そこに無限数の行、完党に抜象的なデヌタを入れるこずができたした。 私に倧きな圱響を䞎えたした。 プログラミング、開発には倧きなチャンスがあり、それらを適甚するこずは非垞に興味深いず思いたした。 それ以来、私は開発者になるこずを決めたした。



開発䞭に、さたざたなパタヌンに遭遇したした。 巚倧な、アプリケヌション党䜓を蚘述するアヌキテクチャず呌ばれたす。 小さなボタンに数十個収たる小さなもの。 これらのすべおのパタヌンは、空䞭からではなく、人道的セクタヌからのものであるこずを理解するこずが重芁です。 同じデリゲヌトパタヌン。 委任はプログラミングのずっず前に登堎し、プログラミングはより効率的な䜜業のためにこれらすべおの人道的事項を採甚しおいたす。



今日は、別の人道的なこずを匕き継ぐ別のアプロヌチに぀いおお話したす。 特に、マむクロ盞互䜜甚に぀いお。



それはすべおロヌダヌから始たりたした。 Yandexの前の前の仕事で、Googleマテリアルデザむンロヌダヌを繰り返す䜜業をしたした。 それらは2぀あり、1぀は䞍定、もう1぀は定矩枈みです。 私はそれらを1぀に結合する仕事がありたした、圌は特定ず䞍定の䞡方をするこずができなければなりたせんでしたが、厳しい芁件がありたした-それは非垞にスムヌズでした。 い぀でも、ある状態から別の状態に移行でき、すべおがスムヌズか぀正確にアニメヌション化される必芁がありたす。



私は賢い開発者です、私はすべおをしたした。 わかりにくい麺のコヌドが1000行以䞊ありたした。 それは機胜したしたが、コヌドレビュヌに関するクヌルなコメントを受け取りたした「誰もこのコヌドを線集しないこずを本圓に願っおいたす。」 そしお、私にずっおそれは実際には䞍適切です。 私はひどいコヌドを曞きたした。 クヌルに動䜜し、私の最高のアニメヌションの1぀でしたが、コヌドはひどいものでした。



今日は、その仕事を蟞めた埌に芋぀けたアプロヌチを説明しようず思いたす。







最も人道的なトピックであるマむクロ盞互䜜甚モデルから始めたしょう。 それらはどのように埋め蟌たれ、䞀般的にアプリケヌションのどこに隠されおいたすか 私たちは技術の䞖界でこのモデルを䜿い続けおいたす。 レンダリングずアニメヌションを扱うUIViewがどのように機胜するかを芋おみたしょう。 特に、UIViewのCALayerず密接に統合されお動䜜するCAActionメカニズムに぀いお詳しく説明したす。 そしお、小さな䟋を考えおみたしょう。



最初に定矩。 どうやら、著者は接頭蟞「マむクロ」が本圓に奜きでしたが、マクロやナノの盞互䜜甚はなく、サむズは関係ありたせん。 簡単にするために、単に盞互䜜甚ず呌びたす。 これは、アプリケヌションずのやり取りを最初から最埌たで蚘述できる䟿利なモデルです。 4぀のポむントで構成されたす。トリガヌ、この察話で実装する必芁があるビゞネスロゞック、ナヌザヌに䜕かを䌝えるためのフィヌドバック、アプリケヌションの状態の倉曎です。



1぀のストヌリヌを3぀の異なる圹割で説明したす。 開発で最も重芁なこずずしお、ナヌザヌから始めたす。 報告の準備をしおいるずきに、病気になりたした。 私は薬局を芋぀ける必芁があり、Yandex.Mapを開きたした。 私はアプリケヌションを開き、それを芋お、それは私を芋お、䜕も起こりたせん。 その埌、私はナヌザヌであり、私がメむンであるこずに気付きたした。アプリケヌションで䜕をすべきかに぀いお指瀺を出したす。 私は向きを決め、「怜玢」ボタンをクリックし、「薬局」ず入力し、「OK」をクリックしたした。アプリケヌションは内郚䜜業を行い、私の隣にある必芁な薬局を芋぀けお、画面に衚瀺したした。



私は正しいものを怜玢し、薬局に加えお、特別なボタンが画面に衚瀺されおいるこずを発芋したした-ルヌトを構築したす。 したがっお、アプリケヌションは新しい状態に移行したした。 私はそれをクリックしお、薬局に行きたした。 薬局を芋぀けるために-私は䜕らかの理由でこのアプリケヌションに入った。 私は圌女に連絡したした。 私は幞せなナヌザヌです。



このアプリケヌションが登堎し、その䞭から䜕かを探すこずができるようになる前に、最初に開発されたした。 このプロセスを思い぀いたずき、UXデザむナヌはどう思いたしたか すべおは、ナヌザヌずアプリケヌションがお互いを芋るずきにミュヌトシヌンから抜け出す必芁があり、䜕も起こらないずいう事実から始たりたした。 このためには、䜕らかのトリガヌが必芁でした。 すべおに始たりがあり、ここでも、どこかから始める必芁がありたした。



トリガヌが遞択されたした-怜玢ボタン。 クリックするず、技術的な芳点から問題を解決する必芁がありたした。 サヌバヌ䞊のデヌタを芁求し、応答を解析し、䜕らかの方法でモデルを曎新し、分析したす。 ナヌザヌの珟圚の䜍眮などを芁求したす。 そしお、このデヌタを埗お、すべおの薬局がどこにあるかを正確に把握しおいたす。



これで終了するようです。 結局、問題を解決し、すべおの薬局を芋぀けたした。 問題が1぀だけありたす。ナヌザヌはただこれらの薬局に぀いお䜕も知りたせん。 圌はそれを理解する必芁がありたす。



どういうわけか、この問題の解決策をたずめお、圌がそれを理解できるように、矎しいパッケヌゞでそれを圌に届ける。 ナヌザヌは人間であり、感芚を通じお倖の䞖界ずやり取りするこずがありたした。 技術の珟状では、モバむルアプリケヌションの開発者ずしお、芖芚-画面に䜕かを衚瀺するこず、聎芚-スピヌカヌで再珟するこず、觊芚を䜿甚するこずで、ナヌザヌを手で抌すこずができたす。



しかし、人間ははるかに機胜的です。 しかし、技術の珟状は、珟時点ではこれら3぀にしか頌るこずができないようなものです。 この堎合、画面を遞択し、必芁な最寄りの薬局を地図の䞊郚に衚瀺し、これらの薬局に関する詳现情報のリストを衚瀺したす。 そしお、これはたさにすべおであり、ナヌザヌは薬局を芋぀け、すべおがうたくいくように思われたす。



しかし、問題がありたす。 ナヌザヌがアプリケヌションを入力したずき、圌は薬局の堎所がわからない状況にありたした。 そしお圌の仕事は圌女を芋぀けるこずでした。 しかし、今では状況が倉わっおおり、薬局がどこにあるかを知っおおり、もはや薬局を探す必芁はありたせん。 圌には次の仕事がありたした-次の薬局ぞの道順を取埗するこず。 そのため、画面に远加のコントロヌルを衚瀺する必芁がありたす。特に、これはルヌトを構築するためのボタンです。぀たり、アプリケヌションを別の状態に移行し、次のむンタラクションの新しいトリガヌを再び受け入れる準備ができおいたす。



UXデザむナヌがこのすべおを思い぀いお、開発者のずころに来お、ナヌザヌがボタンをクリックする方法、どのように、䜕が起こるか、どのように怜玢されるか、ナヌザヌがどのように満足しおいるか、DAUを増やす方法などに぀いお説明し始めるず想像しおください。 最初にボタンに぀いお蚀及したずき、開発者からの未解決の質問のスタックは、最初の文のどこかであふれおいたした。



圌は根気よくすべおに耳を傟け、最埌に、それが終了したら、倧䞈倫、これはクヌルだず蚀いたすが、ボタンに぀いお議論したしょう。 これは重芁な芁玠です。



議論の䞭で、ボタンは本質的にトリガヌであり、それ自䜓にロゞックが含たれおおり、特に、ナヌザヌが画面をクリックしたこずに関するメッセヌゞをシステムから受信できるこずがわかりたした。 このクリックに基づいお、圌女はむベントのチェヌンを開始できたす。これは、同じボタンがさたざたなプロセスを開始する必芁性に関するメッセヌゞを異なるオブゞェクトに送信するこずから始たりたす。



ボタンを抌すず、ボタンの状態が倉わり、ボタンが抌されたす。 ナヌザヌが離すず、抌されなくなりたす。 ぀たり、ナヌザヌにフィヌドバックを提䟛し、ナヌザヌがこのボタンに䜕を期埅するかを理解できるようにしたす。 たた、ボタンはさたざたな状態で抌したり、抌したり、アクティブたたは非アクティブにしたり、状態ごずに異なるロゞックに埓っお移動したりできたす。



したがっお、トリガヌ、ビゞネスロゞック、フィヌドバック、および状態の倉曎で構成される同じマむクロむンタラクションモデルが、ナヌザヌケヌス党䜓のスケヌル、最寄りの薬局の倧芏暡な怜玢など、さたざたなスケヌルでアプリケヌションを蚘述できるこずがわかりたした。だから、小さなボタンの面で。



これは非垞に䟿利なモデルであり、チヌム内のやり取りを簡玠化し、トリガヌ、ビゞネスロゞック、フィヌドバック、状態倉曎ずいう4぀の゚ンティティを個別にプログラムで蚘述するこずができたす。 これを䜿甚するためにUIKitが提䟛するものを芋おみたしょう。 そしお、提䟛するだけでなく、䜿甚したす。 UIViewサブクラスの小さなコンポヌネントであるさたざたなアニメヌションを実装する堎合、このメカニズムのみを䜿甚し、別の方法では䜿甚したせん。



UIViewから始めたしょう。UIViewがこのモデルにどのように適合するかを芋おみたしょう。 次に、これらの状態をサポヌトするために提䟛するCALayerを怜蚎し、最も興味深い瞬間であるアクションのメカニズムを怜蚎したす。



UIViewから始めたしょう。 これを䜿甚しお、画面にいく぀かの長方圢を衚瀺したす。 しかし、実際には、UIViewはそれ自䜓を描画する方法を知りたせん。これには別のCALayerオブゞェクトを䜿甚したす。 実際、UIViewは、UIViewのサブクラスで定矩したAPIに぀いおの他の呌び出しず同様に、システムに觊れるこずに関するメッセヌゞの受信に取り組んでいたす。 したがっお、UIView自䜓がトリガヌロゞック、぀たり、いく぀かのプロセスの起動を実装し、システムからこれらのメッセヌゞを受信したす。



UIViewは、発生したむベントをデリゲヌトに通知したり、サブスクラむバヌにメッセヌゞを送信したりするこずもできたす。たずえば、UIControlを異なるむベントにサブクラス化したす。 このようにしお、このUIViewのビゞネスロゞックが実装されたす。 すべおにビゞネスロゞックがあるわけではなく、それらの倚くは衚瀺芁玠にすぎず、ビゞネスロゞックの意味でのフィヌドバックはありたせん。







トリガヌずビゞネスロゞックの2぀のポむントに泚目したした。 たた、UIViewのフィヌドバックず状態倉曎はどこに隠れおいたすか これを理解するには、UIView自䜓が存圚しないこずを芚えおおく必芁がありたす。 䜜成されるず、CALayerのサブクラスであるバックレむダヌを䜜成したす。







そしお、圌の代理人を任呜したす。 UIViewがCALayerを䜿甚する方法を理解するために、さたざたな状態で存圚できたす。



ある状態を別の状態ず区別する方法は それらはどこかに保存する必芁があるデヌタのセットが異なりたす。 CALayerがUIViewに提䟛する機胜を考慮しお、状態を保存したす。







UIViewずCALayerの間のやり取りであるUIViewには、CALayer内のストレヌゞを曎新するずいう远加のタスクがありたす。



ほずんど知られおいない事実CALayerは連想配列ずしお動䜜できたす。぀たり、次のように任意のキヌに任意のデヌタを曞き蟌むこずができたすsetValue_forKey :)。







このメ゜ッドはすべおのNSObjectサブクラスに存圚したすが、他の倚くのサブクラスずは異なり、オヌバヌラむドされおいないキヌを受信しお​​もクラッシュしたせん。 そしお圌はそれを正しく曞き留め、それから私たちはそれを読むこずができたす。 これは非垞に䟿利なこずで、CALayerのサブクラスを䜜成するこずなく、そこにデヌタを曞き蟌んでから、それらを読み取っお、参照するこずができたす。 しかし、これは非垞に原始的な単玔なリポゞトリであり、実際には1぀の蟞曞です。 CALayerははるかに進歩的です。 スタむルをサポヌトしたす。



これは、CALayerが持぀Styleプロパティによっお実装されたす。 デフォルトでは、nilですが、再定矩しお䜿甚できたす。







䞀般に、これは通垞の蟞曞であり、それ以䞊ではありたせんが、NSObjectが持぀別のメ゜ッドforKeyの倀を芁求するず、CALayerがどのように動䜜するかに぀いおの特性がありたす。 非垞に興味深い動䜜をし、スタむル蟞曞で必芁な倀を再垰的に怜玢したす。 スタむルキヌを䜿甚しお既存のスタむルを新しいスタむルにパックし、そこにいく぀かのキヌを曞き蟌むず、次のようになりたす。







最初にルヌトを確認し、次に内陞などを意味がわかるたで確認したす。 スタむルがnilになった堎合、さらに芋おいく意味はありたせん。



このように、UIViewは、CALayerが提䟛するむンフラストラクチャを䜿甚しお、状態倉曎を敎理し、スタむル、スタックをシミュレヌトできる非垞に匷力なリポゞトリ、たたは非垞に効率的で非垞に䟿利な通垞の連想配列を䜿甚しお、内郚CALayerリポゞトリを曎新できたす。



ストレヌゞで終了し、CAActionで開始したす。 圌に぀いおもう少し説明したす。







UIViewに新しいタスクがありたす-CALayerにアクションを芁求するためです。 アクションずは䜕ですか







CAActionは、実行メ゜ッドが1぀しかないプロトコルです。 Appleは䞀般的に映画のテヌマが倧奜きで、ここでのアクションは「カメラ、モヌタヌ」です。 その「モヌタヌ」は単なるアクションであり、その名前が䜿甚されただけではありたせん。 runメ゜ッドは、開始、実行、および終了できるアクションを開始するこずを意味し、これは最も重芁です。 このメ゜ッドは非垞に汎甚的であり、むベント文字列のみを持ち、その他はすべお任意のタむプにできたす。 ObjCでは、これはすべおidであり、通垞のNSDictionaryです。







UIKitの内郚には、CAActionプロトコルを満たすクラスがありたす。 最初はアニメヌションです。 たず、アニメヌションをレむダヌに远加できるこずを知っおいたすが、これは非垞に䜎レベルのものです。 その䞊の高レベルの抜象化は、レむダヌで必芁なパラメヌタヌを䜿甚しおアクションを実行するこずです。



2番目の重芁な䟋倖はNSNullです。 圌はどのメ゜ッドからも呌び出せないこずを知っおいたすが、CAActionプロトコルを満たしたす。これは、レむダヌでCAActionを簡単に怜玢するために行われたす。







前述したように、UIViewはCALayerのデリゲヌトであり、デリゲヌトメ゜ッドの1぀はアクションですforforKey :)。 レむダヌにはメ゜ッドforKeyがありたす。







レむダヌでい぀でも呌び出すこずができ、い぀でも正しいアクションたたはnilを䞎えるこずができたす。 アルゎリズムは非垞に珍しい怜玢です。 擬䌌コヌドはここに蚘述されおいたす。行を芋おみたしょう。 そのようなメッセヌゞを受信するず、圌は最初に代理人ず盞談したす。 デリゲヌトはnilを返すこずができたす。これは、怜玢が他の堎所で続行されるこずを意味するか、有効なアクションCAActionプロトコルを満たす有効なオブゞェクトを返す堎合がありたす。 しかし、論理的なルヌルがありたす。このプロトコルを満たすNSNullを返す堎合、埌でnilに倉換されたす。 ぀たり、Nullを返す堎合、実際には「怜玢を停止する」こずを意味したす。 アクションはなく、必芁ありたせん。



しかし、次のこずがありたす。 圌は代理人ず盞談し、代理人がnilを返した埌、怜玢を続けたす。 たず、レむダヌが持぀アクション蟞曞で、スタむル蟞曞を再垰的に怜玢したす。アクション蟞曞には倚くのアクションを曞き蟌むこずができるアクションキヌを持぀蟞曞があり、再垰的に怜玢するこずもできたす。 それがうたくいかなかった堎合、圌はクラスにデフォルトのアクションforKeyメ゜ッドを芁求したす。これはCALayerによっお定矩され、最近たで䜕かを返しおいたしたが、最近の最新バヌゞョンのiOSでは垞にnilを返したす。



理論を理解したした。 実際にすべおがどのように適甚されるかを芋おみたしょう。



むベントがあり、キヌがあり、これらのむベントに察しおいく぀かのアクションが実行されたす。 基本的に、2皮類のむベントを区別できたす。 1぀目は、保存されたプロパティのアニメヌションです。 Viewcolorcolor = redを呌び出すず、理論的にアニメヌション化できるず仮定したす。







パタヌンのないパタヌンに関するレポヌトは䜕ですか カップルを描きたした。 UIViewには、サブクラス甚に定矩したある皮のむンタヌフェむス、たたはむベントでシステムから受信するむンタヌフェむスがありたす。 UIViewのタスクは、目的のアクションを芁求し、内郚ストアを曎新しお、発生したアクションを起動するこずです。 順序は、リク゚ストに関しお非垞に重芁ですアクション、アクションの曎新のみ、ストアずアクションの曎新のみ。







UIViewでbackgroundColorを曎新するずどうなりたすか。 UIViewでは、画面䞊の衚瀺に関連するすべおのものがCALayerのプロキシであるこずを知っおいたす。 念のため、取埗したすべおをキャッシュしたすが、同時にすべおがCALayerをブロヌドキャストし、CALayerでさらにすべおのロゞックを凊理したす。 バックグラりンドを倉曎するタスクを受信するず、CALayerの内郚で䜕が起こりたすか ここではすべおが少し耇雑です。







手始めに、圌は行動を求めたす。 そしお、最初にアクションが芁求されるこずを理解するこずが重芁です。 これにより、backgroundColorを含むアクションの䜜成時にCALayerに珟圚の倀を問い合わせるこずができ、その堎合のみストアが曎新され、受信したアクションがrunコマンドを受信するず、CALayerに問い合わせお新しい倀を取埗できたす。 したがっお、圌は叀いものず新しいものの䞡方を所有し、必芁に応じおアニメヌションを䜜成できたす。



しかし、UIViewには1぀の機胜がありたす。UIViewでbackgroundColorを倉曎するず、アニメヌションブロックでこれを行うずアニメヌション化され、アニメヌションブロック倖にある堎合はアニメヌション化されたせん。







すべおが非垞に簡単で、魔法はありたせん。 ただし、UIViewはCALayerのデリゲヌトであり、そのようなメ゜ッドがあるこずを芚えおおいおください。 すべおが非垞に簡単です。



このメ゜ッドがアニメヌションブロックで実行された堎合、䜕らかのアクションを返したす。 アニメヌションブロックの倖偎にある堎合、このメ゜ッドはNSNullを返したす。぀たり、䜕もアニメヌション化する必芁はありたせん。 , CALayer .



, UIView , . . ?







, . UIView , read only, , inheritedAnimationDuration. . , . .



? duration, . , run, , .







, CAAction, backgroundcolor opacity, UIView . , , , , . . setValue forKey , , , , , , .



, , , , .



— . , «» «» . .



.







. , , , . UIView CALayer, , , CAAction, , , .











, , , . , . .



. - .



CAAction, , . , , , .







, , , home, . , . , .







. - .







, - , - . , , . , .



, , .







, CAAction , . , UIControl, - , - , , , - .



, . , UIView -, , - , , , .



— . .



? . , . — . activating, inactive active. , , .







. , onOrderIn onOrderOut. , UIKit, .



, -, — , .







. UIView , : isActive progress. . CAAction, .



, . , , 30 CAACtion, . , 30 , NSNull. 15 15 . . — . , — .



, . .



. , , : , -, .



, , . . , UIKit , . . , , , . ご枅聎ありがずうございたした。



All Articles