Swiftで遊ぼう! on Hatena

あしたさぬきblogでやってた初心者オヤジのiOSプログラミング奮闘記がHatenaに来ました

Swiftで遊ぼう! - 1006 - Layout-Driven UI を極めるための一歩

WWDC2018のビデオを見ていると、何でも簡単に実装できそうに思えるのですが自分で試そうとすると、直ぐに行き詰まってしまいます(T_T)

「Adding Delight to your iOS App」のLayout-Driven UIトレーディングカードの動きを実装しようとしてるんですが、最初の簡単なデモからちゃんと動かないんです。壇上の二人はシンプルで簡単に実装できるって言ってるんですけどね。

簡単なデモが紹介されているけど、「Cool Guy」のコードがその例です。カンファレンスで示されているMyViewクラスは、CoolViewクラスをサブビューとして持っていますが、シンプルにするためにサブビューは省きました。

class MyView: UIView {
    
    var feelingCool = true {
        didSet {
            setNeedsLayout()
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.isHidden = !feelingCool
    }
}

プロパティ・オブザーバーで値の変化を監視して描画させるというのは旨いやり方ですね。これを実装すると、feelingCoolの値が変化するたびに、このクラスのインスタンスが出現したり消えたりします。ちゃんとLayoutが変化してるんです。しかし、切り替えは一瞬です。パッパッと切り替わるので美しくはありません。プレゼンテーションではCool Guyがジワーっと出現したり消えたりしています。

じゃあこのシンプルなデモにUIViewPropertyAnimatorクラスでアニメーションを加えてみました... あれこれコードを試してみてもうまく動かないんです。

一人で勉強していて困ることは、分からないところに直面すると解決するのに時間がかかるところです。ネットで情報を探してみてもなかなか答えが見つかりません。

こういう時はアップルの公式ドキュメントを読むのが一番いい方法のようですね。UIViewPropertyAnimatorを調べてみると、アニメーションを加えることができるプロパティは次のものだけということを知りました。

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor

これで理解できました!メソッド「.isHidden」でアニメーションになりませんね。ということで次のようにコードを書き換えました。

class MyView: UIView {

    var feelingCool = true {
        didSet {
            setNeedsLayout()
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        if feelingCool {
            self.alpha = 1
        } else {
            self.alpha = 0
        }
    }
}

おお!これでアニメーションがちゃんと動きました!次はジェスチャーとの組み合わせに関してもう少し勉強します。

Swiftで遊ぼう! - 1005 - Layout-Driven UIを考えていく

WWDC2018の「Adding Delight to your iOS App」のセッションを見ていて、アップルのトレーディングカードをグリグリ動かしていたのでワクワクしました。レイアウト単位でアニメーションを動かすLayout-Driven UIの勉強を始めます...

アニメーションの知識が全く無い!

結局WWDC2016ぐらいまで遡ってアニメーションの実装法学ぶことになったので、またまた理解に時間がかかっています。

基本的にユーザーインターフェイスにアニメーションを組み込むために利用するクラスはUIViewPropertyAnimatorといういうことは分かりました。UIに対してインタラクティブに反応することができるからです。

まずはタップに組み込み...

なんか一筋縄ではいきません。

もう少し理解が進んだらブログを続けます。

Swiftで遊ぼう! - 1004 - Xcode 10 beta 2

プログラミングの勉強してます。

まだまだ理解できていない内容なのでブログに書き残せない状態です。WWDC2018の動画で紹介されているプログラミングスタイルを自分で実装しようとしているのですが、WWDC2017やWWDC2016の内容を理解していないとできないことでした。

昔の内容を復習しながら新しい内容の勉強をしています。

そんかことしているとβ版の開発環境がバージョン2にアップデイトされていました。

これからダウンロードしてインストールします。

Swiftで遊ぼう! - 1003 - forEach(_:)

何事も毎日ちょっとずつちょっとずつ。

今日は単なる備忘録(^_^;)

forEach(_:)

連続するデータ(シークエンス)で使えるインスタンス・メソッドです。

func forEach(_ body: (Int) throws -> Void) rethrows

あれ? rethrowsの使い方も分かってないな?

let numberWords = ["one", "two", "three"]
for word in numberWords {
    print(word)
}
// Prints "one"
// Prints "two"
// Prints "three"

numberWords.forEach { word in
    print(word)
}
// 上に書いているコードと同じ結果

これは便利ですね。覚えておこう。

Swiftで遊ぼう! - 1002 - ちょっとKVOを復習

Core Dataの勉強をしているんですが、Key値を使ってValue値を取り出すことができるDIctionary型をみていて「Key Value Observing(KVO)」デザイン・パターンを思い出しました。

このデザイン・パターンは、iOSシステムに利用されていて、NSNotificationクラスが典型的なKVOデザイン・パターンだと思います。

しかし、このNotificationを独自に作ることはできないようなので、カスタムクラスの監視をしたい場合は、KVOを独自に組み込んでいく必要があるんです。

このデザイン・パターンに関する勉強を以前しました。Swift 4になって少し機能拡張がありましたが、それほど大きな変更は無かったようです。Appleは、NSNotificationクラスの拡張に注力しているようですね。

下記のリンクをSwift 4.2向けに書き換えました。

yataiblue.hatenablog.com

Swiftで遊ぼう! - 1001 - 新たに再出発の誓い... Core Dataに取り組む

長い中断があり、50親父のアプリ開発計画も中断しそうになっていました。プログラミング勉強に割ける時間も僅かで、集中して勉強できないので仕方ないかもしれませんね。理解力もかなり落ちていて他人のコードが読めない(理解できない)ことも多々あります。

Swift言語の変化についていくのも大変です。勉強をはじめた頃はバージョン1だったのに、3年で4.2まで変化を遂げました。Swift言語はダイナミックに変化しているけど、未だにiOSの深層ではobjective-cも脈々と動き続けており、その理解も必要な時があります(T_T)

まあ、愚痴を言っていても仕方ないのでCore Dataの勉強に取りかかります。

Swift 3で導入されたNSPersistentContainerクラスは、データーベースであるSQLiteを利用すためのAPIを統括するような立場です。

データーベースで扱うデータは、一つ一つentity(エンティティー)と呼ばれます。これはNSManagedObjectクラスのインスタンスとして扱われるんです。複数のNSMangaedObjectクラスをまとめるのがNSManagedObjectModelで、それをコントロールするのがNSPersistentContainerと考えればいいでしょう。

プロジェクトを作成するときに「Use Core Data」チェックマークを入れておくと、Core Dataに関する初期ファイルが色々導入され初心者には便利です。しかし、このチェックマークは万能ではありません。色々と手入れしないと使えないんです。

まず、「プロジェクト名.xcdatamodeld」というファイルが作られています。これがデータ・モデル(NSManagedObjectMode)です。ビジュアルにentityを設定することができるのでデーターベース設計をするのが楽しくなるでしょう。

Swiftで遊ぼう! - 612 - CoreDataMyDemo - Swiftで遊ぼう! on Hatena で扱っているCoreDataMyDemo.xcdatamodeldをみると、entityは「Users」です。このentityは「NSManagedObject」クラスです。

ここでUtilitiesエリアからData Model Inspectorを選択すると以下のイメージ*1のように、「Codgen」という項目があり、デフォルトでは「Class Definition」が選択されています。クラスとして扱えるけど、コードでカスタマイズできません。

f:id:yataiblue:20180614132403j:plain

コードでカスタマイズできないということは、コードで扱うとき、必ず「NSManagedObject」クラスとして取り扱う必要があり少し面倒くさいです。カスタムクラスで扱うために、「Manual/None」を選択して、Moduleに「Current Product Module」を選んで、メニューの「Editor」→「Create NSManagedObject Subclass...」を選ぶと、NSManagedOnjectのサブクラスである「Users」クラスが生成されます。

let entity = 
  NSEntityDescription.entity(forEntityName: "Users", in: context)
        
let user = Users.init(entity: entity!, insertInto: context)
user.username = "Yuji"
user.password = "1234"
        
do {
    try context.save()
            
} catch let error as NSError {
    print("Error: \(error)")
}
        
let request = 
  NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
        
do {
    let result = try context.fetch(request)
    for data in result as! [Users] {
        print(data.username!)
        print(data.password!)
    }
            
} catch let error as NSError {
     print("Error: \(error)")
}

上記のように書き換えるとUsersクラスを扱えるようになり、そのプロパティである「username」や「password」を簡単に変更できるようになります。こうした方が便利ですよね。

*1:このイメージはXcode9.4です。Xcode10.0はβ版のためイメージが使えません

Swiftで遊ぼう! - 1000 - まだまだ道半ばで奮闘中... Core Data

「Swiftで遊ぼう!」シリーズも今日の記事で1000回目です。パチパチパチ!

50親父のSwiftプログラミング、何度も挫折しそうになりながら続けています。

ド素人だったんですが、少し分かるようになりました。Core Dataがもう少し使えるようになって、ユーザーインターフェイスのデザインができるようになったらオリジナルアプリに取りかかろうと思います。

シンプルなオリジナルアプリを作って、AppStoreで公開するところまでこぎ着けたら一段落ですね。

Core Dataを使ったシンプルデモの後半部分をSwift 4.2でも動くようにコードを書き換えました。実はSwift 4.2が公開されたのですが、Core Data の大きな変更は無かったのでSwift 4向けに変更と言っていいでしょう。

yataiblue.hatenablog.com

昨日の記事に追記が入っています。