UIKit - tintColorについて調べた
本を読んでいたら、tintColorについて発見があったのでメモ。
単にUIの色を変えるという認識でした。
親のビューのtintColorを変更すると、子のビューのtintColorが変更される
let parentView = UIView() let stepper = UIStepper() stepper.tintColor = UIColor.yellowColor() // 黄色を設定 parentView.addSubview(stepper) parentView.tintColor = UIColor.blueColor() // 子供すべてのtintColorが青色に変更される
さらに、tintColorにnilを代入すると、親のtintColorがあてがわれる。
let parentView = UIView() parentView.tintColor = UIColor.redColor() let stepper = UIStepper() stepper.tintColor = UIColor.greenColor() stepper.tintColor = nil //親の赤色がtintColorに設定される
tintColorを変更すると、変更したビューではtintColorDidChangeがコールされる
さらにtintColorを変更するとコールされるメソッドもあった。
let parentView = MyView() parentView.tintColor = UIColor.redColor() class MyView: UIView { override func tintColorDidChange() { print(tintColorを赤色に変更した) } }
まだまだ知らないことがたくさんありますね〜。
絶賛ブランクを埋めるために、以下の本を読んでUIKitについて学び直してます。
小手先のテクニックではなくて、UIKitについてしっかり書かれているので学びがとても多いです。
CoreGraphics - CGRect, CGPointが短形内にあるかどうかを調べる
短形A、ポイントAが短形Bの範囲内にあるかどうか、
調べるには以下のメソッドを使うようだ。
// 短形を調べる場合 CGRectContainsRect(rect1: CGRect, _ rect2: CGRect) -> Bool // ポイントを調べる場合 CGRectContainsPoint(rect: CGRect, _ point: CGPoint) -> Bool
知らなんだ。
Swift - 文字列の計算式を計算する
"3+5/2"のような文字列の計算式の答えを求めるには、以下のように書きます。
let expression = NSExpression(format: $計算式文字列$) let result = expression.expressionValueWithObject(nil, context: nil) as? NSNumber
resultには、正確な計算式であれば答えとなるNSNumberが、計算式でなければnilが返ってきます。
Javascriptのevalのようなものですね。
"5/3"が計算式だとすると数字は全てIntなので、小数点の答えは出ません。
小数点まで求めるのであれば、計算式内の数字を正規表現かなにかで、
”X.0”としてやればDouble型になるので、小数点の答えも出るのではないかと思います。
参考:
UIKit - TableViewCellの高さについて
しばしブランクが合ったので、UITableViewCellの高さの設定が以前とちがっていました。
忘れないようにメモる。
UITableViewCellの高さが一定ならば、UITableViewのrowHeightプロパティに入れるだけで良い。
let tableView = UITableView() tableView.rowHeight = 80 // 高さが一定値
UITableViewDelegateのheightForRowAtIndexPathに入れると、
セルの数だけ呼び出されるので無駄が多いとのこと。
UIKit - オリジナル画面遷移を作ってみる(1)
とっても今更だが、オリジナルの画面遷移ができる方法をしっておきたかったので、
テストがてら簡単なものをつくって自分なりにまとめる。
今回はモーダルで開くときの画面遷移をオリジナルにしたが、
同様のやり方でUINavigationControllerのPush/PopやUITabControllerの切り替えにも対応できる。
必要なもの
・MainViewController(遷移元のViewController)
・ModalViewController(遷移先のViewController)
・AnimationController(遷移のアニメーション処理を受け持つクラス。UIViewControllerAnimatedTransitioningを実装)
遷移元と遷移先のViewControllerは当たり前として、
UIViewControllerAnimatedTransitioningプロトコルを実装したクラス一つ作り、
遷移元にUIViewControllerTransitioningDelegateを実測してやれば、
簡単にカスタム遷移を実現することができます。UIKit便利ですね。
アニメーションコントローラーの作成
遷移アニメーション処理を受け持つクラスを作成します。
ここでは、遷移元ビューコントローラーでpresentationViewControllerした時に、
登場時(presenting==true)のときには、右から新たなビューコントローラーが出てくるように、
退去時(presenting==false)のときには、右に表示ビューコントローラーが消えていくようにアニメーションさせています。
class SlideAnimationController: NSObject, UIViewControllerAnimatedTransitioning{ let presenting: Bool init(presenting: Bool) { self.presenting = presenting super.init() } // アニメーションにかける時間 func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { return NSTimeInterval(0.6) } // アニメーション func animateTransition(transitionContext: UIViewControllerContextTransitioning) { guard let containerView = transitionContext.containerView(), fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey), toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) else { return } let fromView = fromVC.view let toView = toVC.view let inframe = transitionContext.initialFrameForViewController(fromVC) let outframe = CGRectOffset(inframe, CGRectGetWidth(inframe), 0) if presenting { containerView.addSubview(toView) toView.frame = outframe UIView.animateWithDuration(self.transitionDuration(transitionContext), animations: { toView.frame = inframe }, completion: { (finished) in transitionContext.completeTransition(!transitionContext.transitionWasCancelled()) }) } else { containerView.insertSubview(toView, belowSubview: fromView) toView.frame = inframe UIView.animateWithDuration(self.transitionDuration(transitionContext), animations: { fromView.frame = outframe }, completion: { (finished) in transitionContext.completeTransition(!transitionContext.transitionWasCancelled()) }) } } }
遷移元ビューコントローラーにUIViewControllerTransitioningDelegateを実装します
// MainViewController func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return SlideAnimationController(presenting: true) } func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return SlideAnimationController(presenting: false) }
あとは遷移するだけ
let modalVC = ModalViewController() modalVC.transitioningDelegate = self modalVC.modalPresentationStyle = .FullScreen // .FullScreen or .Customを設定する presentViewController(modalVC, animated: true, completion: nil)
案外簡単にできたので、次はユーザー操作に合わせて画面遷移させてみたいと思います。 コードはこちら↓
UIKit - セルの選択状態を無色にしたい
忘れていたのでメモがわり。
selectionStyleを.Noneに設定すればよし。
MyCell.swift override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.selectionStyle = .None }
Swift - 自作クラスをEquatableプロトコルに準拠させる
自作クラスである、以下の様なMemberクラスがあったとします。
class Member { let id: String let name: String init(_ id:String, _ name: String) { self.id = id self.name = name } }
同一人物かどうかを判断するために、
以下のように「==」や「!=」での比較を行いたいと思いました。
let memberA = Member("01", "Taro") let memberB = Member("01", "Masami") if memberA == memberB { print("同じ人") } else { print("違う人") }
等値演算子に利用するには、
自作のMemberクラスをEqutableプロトコルに準拠させなければなりません。
ということで、以下のように書くと上記の書き方が叶います。
こういうのを「演算子のオーバーロード」と言うらしい。
func == (left : Member, right : Member) -> Bool { return left.id == right.id } extension Member: Equatable {} class Member { let id: String let name: String init(_ id:String, _ name: String) { self.id = id self.name = name } }
この例ではイマイチですが、リンク先のように日付先などを比べるにあたって、
コードが見づらくなる時などには良いかもしれませんね。