無限ループ
UICollectionViewを継承したクラスをつくり、layoutsubViewsで中心からコンテンツが1/4程度外れていたらContentOffSetを中央へ移動させるようにすれば良い。
let totalContentWidth = CGFloat(cellCount) * cellWidth let centerOffsetX = totalContentWidth / 2 - self.bounds.width / 2 let distFromCentre = centerOffsetX - contentOffset.x if (fabs(distFromCentre) > totalContentWidth / 4) { let moveOffsetX = CGFloat(centerRow()) * cellWidth if contentOffset.x < centerOffsetX { self.contentOffset = CGPoint(x: moveOffsetX , y:contentOffset.y) } else if contentOffset.x > centerOffsetX { self.contentOffset = CGPoint(x: moveOffsetX , y:contentOffset.y) } }
centerRow()は
func centerRow()->Int { guard contentCount > 0 else { return 0 } let row = Int(cellCount/2/contentCount) * contentCount return row }
contentCountはコンテンツの数
cellカウントはセルの数(コンテンツの数の倍数ないし無限)
BehaviorSubject
BehaviorSubjectは最後の値を覚えていてsubscribeで即座に値が返ってくる。最初の値はこちらで指定できる。
class Temperature { private let behaviorSubject = BehaviorSubject(value:0) var behavior : BehaviorSubject<Int> { return behaviorSubject } func doSomething(x:Int) { behavior.onNext(x) } }
のように初期値入りで定義しておく。
Observableと同様に登録すると、即座に最後の値(今回は初期として渡された0)を返してくる。
_ = temperature.behavior.subscribe( onNext:{ label2.text = "\($0)"}, onError: {_ in }, onCompleted: { print("end")}, onDisposed: { print("disposed")})
UITextViewの縦方向の中央寄せ
contentSizeをオブザーブして
textView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
contentSizeに変化があれば、中身を調節する。
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if let textView = object as? UITextView { var topCorrect = (textView.bounds.size.height - textView.contentSize.height * textView.zoomScale) / 2 topCorrect = topCorrect < 0.0 ? 0.0 : topCorrect; textView.contentInset.top = topCorrect } } deinit { textView.removeObserver(self, forKeyPath: "contentSize") }
Observable
次のようなクラスを定義する。
class Temperature { private let eventSubject = PublishSubject<Int>() var event: Observable<Int> { return eventSubject } func doSomething(x:Int) { eventSubject.onNext(x) } }
テキストフィールドの編集が終わったタイミングで数を数えるということにしてみた。正しい書き方かはわからない。
_ = textFiled?.rx.controlEvent(UIControlEvents.editingDidEnd).subscribe { event in self.temperature.doSomething(x: self.textFiled!.text!.lengthOfBytes(using: .utf16)) } disposeTemp = temperature.event.subscribe( onNext: {print("\($0)")} , onError: {_ in }, onCompleted: { print("end")}, onDisposed: { print("diposed")} )
とめたいときはdisposeTempをdispose()すれば良い。
継続モナド
継続モナドはSwiftで段階的に作れる。
1. まず継続渡しの関数を作る。
func getA(complete:(String)->Void) { complete("X") }
2. 継続渡しの関数を引数にとるクラスを作る。
typealias Func<T> = (T)->Void public struct RDFuture<T> { public var f:(Func<T>)->() public func result(_ complete:(T) -> Void) -> Void { f(complete) } init(_ f:@escaping (Func<T>)->()) { self.f = f } }
これで骨組みはできた。
このように使う
func test() { let f = RDFuture(getA) f.result { print($0) } }
これに、bind的な実装をつけることになる。
Realm
Realmを試してみた。便利だ。。
import Foundation import RealmSwift class Man : Object { // ObjectはRealmのクラス dynamic var name = "" // dynamicはobjective-Cのランタイムを利用して値にアクセスする dynamic var age = 10 let cats = List<Cat>() // ListはRealmのクラス } class Cat : Object { dynamic var name = "" let owners = LinkingObjects(fromType: Man.self, property: "cats") } class Test { func test() { let man = Man() man.name = "ho" man.age = 5 let cat = Cat() cat.name = "mi" let realm = try! Realm() try! realm.write { realm.deleteAll() realm.add(man) realm.add(cat) let man = realm.objects(Man.self).filter("name == 'ho'").first! man.cats.append(cat) } let babies = realm.objects(Man.self).filter("age < 2") print("\(babies.count)") DispatchQueue(label: "background").async { autoreleasepool { let realm = try! Realm() let men = realm.objects(Man.self) let man = realm.objects(Man.self).filter("age == 5").first! try! realm.write { man.age = 10 } let cat = realm.objects(Cat.self).filter("name == 'mi'").first! print("\(man.cats.first?.name)") print("\(cat.owners.count)") let babies = realm.objects(Man.self).filter("age == 10") print("\(babies.count)") } } } }
proxy
export USERNAME= export PASSWORD= export HOST= export PORT= export PROXY=$USERNAME:$PASSWORD@$HOST:$PORT export http_proxy=http://$PROXY export https_proxy=https://$PROXY export ftp_proxy=ftp://$PROXY export HTTP_PROXY=http://$PROXY export HTTPS_PROXY=https://$PROXY export FTP_PROXY=ftp://$PROXY export no_proxy= export NO_PROXY=$no_proxy
以下を参照した。
プロキシ下でLinuxを使う際のメモ - Λlisue's blog
コレクションビューの隙間
水平な線形レイアウトで隙間を調整したい時、しかもminimumをなくしたいと考えた時、ラインも修正すると良い。
セクション
セクションは流れていく。それを止めるには
stackoverflow.com
画面の一部を切り取る
resizableSnapshotView
これとUIView.transitionを組み合わせて一部分の画面遷移を再現できる。
viewWillLayoutSubviews
viewWillLayoutSubviewsはviewのlayoutSubviewsの前に呼ばれる。
ちなみにlayoutSubviewsはレイアウト更新タイミング、制約つけたいときはupdateConstraints。
viewWillLayoutSubviewsは結果的にViewWillAppearとViewWillDidAppearの中間で呼ばれることになる。