【swift】UITableViewCellの選択した時の表示を変更する
selectionStyle
を変更するだけです。
import UIKit class CustomCell: UITableViewCell { override func awakeFromNib() { super.awakeFromNib() // Initialization code selectionStyle = .None } }
【android】エミュレータのhostsを書き換える
Android Debug Bridge (adb) を使用して ローカルにあるhostsファイルをエミュレータ上に配信させて書き換えます。
まず、エミュレータをroot権限で操作できるように設定します。
$ adb root
remountします。
$ adb remount
127.0.0.1のまま差し替えちゃうとエミュレータ自身を見に行ってしまうので、自PCのプライベートIPに差し替えます。
(192.xxxの部分は適宜書き換えてください)
$ cat /etc/hosts | gsed 's/127.0.0.1/192.168.1.9/' > /tmp/hosts-adb
エミュレータ上にhostsを配信します。
$ adb push /tmp/hosts-adb /system/etc/hosts
【swift】コードでAutoLayout その1 - Visual Format Language
コードでAutoLayoutを記述します。
iOSにはVisual Format LanguageというAutoLayoutを直感的に定義できるフォーマットが用意されており、使い方さえ覚えてしまえばちょっとした制約であればサクッとコードで書けてしまいます。
使ってみる
とりあえず、AutoLayoutを適用するためのViewを用意してみます。
let wrapperView = UIView() wrapperView.backgroundColor = .redColor() wrapperView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(wrapperView)
この時、大事なポイントが二つあります。
1. translatesAutoresizingMaskIntoConstraints を falseにする
詳しくは理解していないですが、AutoLayoutを使用する場合は、昔からあるレイアウトシステムのAutoresizingMaskをfalseにする必要があります。
2. AutoLayoutの制約を定義する前にaddSubviewを実行する
Visual Format Languageで制約を設定する場合、superviewに対して位置を設定したりするため、制約を定義する前にviewに追加しておく必要があります。
制約の定義
制約の定義には、addConstraints
を使います。
let views = ["wrapperView": wrapperView] // 左右の位置をsuperviewとくっつける view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat( "|-0-[wrapperView]-0-|", options: .AlignAllTop, metrics: nil, views: views)) // 上下の位置をsuperviewとくっつける view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat( "V:|-0-[wrapperView]-0-|", options: .AlignAllTop, metrics: nil, views: views))
|-0-[wrapperView]-0-|
この記述が、Visual Format Languageです。
|
がsuperviewを表し、対象のviewは[]
で囲みます。
V:
という記述で縦の結びつきを表します。
views
で渡したディクショナリから文字列の変数展開を行い、AutoLayoutが定義されます。
これで、画面いっぱいにwrapperViewが広がるようになりました。
とりあえず今日はここまで。
【swift】対象のビューのAutoLayoutを計算した後のCGSizeを取得する
tableViewCellの高さ計算の時など、コード上で対象のViewのAutoLayoutを計算した後のサイズを取得したい時があります。
そんな時は、systemLayoutSizeFittingSize
を使います。
引数で渡す値に応じて、コンテンツを表示するための最小サイズか、最大サイズのCGSizeを返します。
サイズ計算時にはサブビューを含めたすべての制約が考慮されます。
// コンテンツを表示するための最小サイズを指定する let minSize = view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) // コンテンツを表示するための最大サイズを指定する let maxSize = view.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize)
【swift】【iOS】UIViewからUIImageを生成する
facebookに写真をシェアしたい時などに、アプリ側で組みて立てたUIViewからUIImageを生成したい時があります。
例えばアプリ側でこんなViewを組み立ててみます。
これはソースコードは雑につくるとこんな感じです。
5つのUIViewで組み立てられています。
let containerView = UIView(frame: CGRectMake(160, 200, 200, 200)) let view1 = UIView(frame: CGRectMake(0, 0, 50, 50)) view1.backgroundColor = UIColor.redColor() containerView.addSubview(view1) let view2 = UIView(frame: CGRectMake(50, 0, 50, 50)) view2.backgroundColor = UIColor.yellowColor() containerView.addSubview(view2) let view3 = UIView(frame: CGRectMake(0, 50, 50, 50)) view3.backgroundColor = UIColor.greenColor() containerView.addSubview(view3) let view4 = UIView(frame: CGRectMake(50, 50, 50, 50)) view4.backgroundColor = UIColor.blueColor() containerView.addSubview(view4)
このcontainerViewからUIImageを生成します。
let image: UIImage? // 第2引数は画像が不透明の場合はtrue // 第3引数は倍率(scale) UIGraphicsBeginImageContextWithOptions(containerView.frame.size, false, 1) containerView.layer.renderInContext(UIGraphicsGetCurrentContext()!) image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext()
これでUIImageの出来上がりなので、これを使用してシェアをするなり、UIImageViewにしちゃうなり、なんでもありです。
Tips
ここで生成したimageの見た目を確認する簡単な方法がxcodeには搭載されています。
imageが生成されたタイミングでブレークポイントを設定して処理を止めた後に、該当の変数にマウスオーバーすることで下記のような吹き出しが出てきます。
そして、この目玉みたいなアイコンをクリックすると、実際の画像がプレビューされるので、わざわざ画面に描画することなく生成した画像を確認することができます。
【iOS】【swift】カスタムViewとxibを紐付ける
swiftで独自のViewを定義した時に、見た目をxibで整える方法をまとめます。
1. 独自のViewクラスの定義
class CustomView: UIView { }
2. 空のxibファイルを作成
3. xibで見た目を作成
4. File's Ownerで先ほどの独自Viewクラスを指定
これで、とりあえずxibファイルとViewクラスが紐付いたので、各要素のOutletやActionを定義できるようになります。
5. Viewクラス側でxibファイルを読み込み、xibファイルで定義した一番親のViewを追加する
File's Ownerでクラスを指定しただけでは、xibファイルを読み込むことはしません。(してくれればいいのに)
Viewクラス側で明示的に読み込んであげる必要があります。
xibファイルを読み込むにはloadNibNamed
を呼び出します。
// xibファイル名を指定 NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil)
loadNibNamed
を呼び出したとしても、まだカスタムViewには要素は何も入っていない状態です。(入ってくれればいいのに)
xibファイルの親のViewをaddSubview
で明示的に追加してあげる必要があります。
カスタムViewクラスの全体をまとめるとこんな感じになります。
class CustomView: UIView { // xibファイルで定義した一番親のView @IBOutlet var contentView: UIView! override init(frame: CGRect) { super.init(frame: frame) // xibファイル読み込み NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil) // Viewの大きさを定義 bounds = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 44) contentView.frame = bounds // xibファイルのViewをカスタムViewクラスに追加する addSubview(contentView) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
これで、このカスタムViewの見た目をxibファイルで整えられるようになります。
紐付けた後に、わざわざaddSubview
で追加しないといけないというのが、ちょっとイメージしづらいなと思いました。
【iOS】【Swift】convertRectを使ってframe位置を計算する親要素を変更する
要素の座標位置を取得するためには、その要素のframeを見ます。
view.frame.minX view.frame.minY
この時の座標位置は親要素から見た時の相対的な位置になります。
例えばviewが3階層の構造になっている場合、それぞれの座標位置は下記のようになります。
- 黄色いView: grandParentView
- 赤いView: parentView
- 青いView: childView
childViewはparentViewからの位置、parentViewはgrandParentViewからの位置になります。
この時、childViewの位置をgrandParentViewから計算して取得したい場合があります。
単純に考えれば、childViewの座標にparentViewの座標を足せば導き出せます。
parentView.frame.minX + childView.frame.minX parentView.frame.minY + childView.frame.minY
ですがこれだと計算を自分で書くことになりバグを生みやすくなるので、かわりにconvertRectを使います。
let convertFrame = parentView.convertRect(childView.frame, toView: grandParentView)
convertRect:toViewは、第一引数のframeの位置をtoViewで渡した要素から計算して、新しいCGRectを返します。
これでchildViewの座標位置をgrandParentViewから計算して導き出すことができました。