#StoryBoardなしLINE風のテキストエリアUI作成
ベッキーだの清原だの甘利だの言うてるこのご時世に、StoryBoardのトラップに苦しめられていました。いっその事餅つき大会にパンしか食わねえぞTシャツを着て行こうかと思いましたが、やはりそれは人としていかんと思いコードで書き直しました。
#概要
とういことでLINE風UIをコードのみで描画してみました。
#####環境:xcode 7.2 + swift2
ビジネスロジックは割愛します。
3つのUIパーツを作っていきます。
bottomBar
L> textField
L> button
buttomBarがtextFieldとbuttonを持っているイメージです。
#パーツ作成
bottomBar, textField, buttonのパーツ作っていきます。
上部の真っ白の部分はTableViewでもピカチュウでもベッキーでも配置してください。
それではsetUIメソッド(名前は自由)を用意して中にコードを書いていきます
viewDidLoadの中でも動きますし、もっと細かく分けてもメソッドを分けてもいいです。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setUI()
}
private func setUI(){
//ここに書いていきます
}
##bottomBar
private func setUI(){
let bottomBar = UIView(frame: CGRectMake(0, self.view.frame.height - 50, self.view.frame.size.width, 50))
bottomBar.backgroundColor = UIColor(red:0.85, green:0.85, blue:0.85, alpha:1.0)
}
##button
setUIの中に書き足していってください。
// CGRectMakeでパーツ描いていきます
let button = UIButton(frame: CGRectMake(0, 0, 80, 30))
// バックグラウンド色指定
button.backgroundColor = UIColor(red:0.25, green:0.60, blue:0.75, alpha:1.0)
// セットタイトル *button.titleLable?.textは読み取り専用なのでsetには使わないでください
button.setTitle("sumbit", forState: .Normal)
// 文字指定 フォントFutura通称古田を指定します
button.titleLabel?.font = UIFont(name: "Futura", size: 14)
// 文字色ーーー
button.setTitleColor(UIColor.whiteColor(), forState: .Normal)
// 角丸ーー
button.layer.cornerRadius = 5.0;
##textField
RoundedRectの場合、storyboard上で高さ変更不可ですが、コードだと変更できます。
let textField = UITextField(frame: CGRectMake(0, 0, self.view.frame.size.width * 0.7, 30))
// textFieldのボーダースタイル。.RoundedRectは角丸のやつです
textField.borderStyle = .RoundedRect
#translatesAutoresizingMaskIntoConstraints(長っ)
パーツ作成終了とConstraintsをうまく起動させるための小細工(重要)
translatesAutoresizingMaskIntoConstraints をfalseにしてください
これがないとConstraintsのコードがうまく反映されません。これを発見するのに15年かかりました。
button.translatesAutoresizingMaskIntoConstraints = false
bottomBar.translatesAutoresizingMaskIntoConstraints = false
textField.translatesAutoresizingMaskIntoConstraints = false
#UIを追加ーー
UIを追加する前に、Constraintsを追加すると落ちます。見やすいようにまとめて追加したほうが良いと思います。
view.addSubview(bottomBar)
bottomBar.addSubview(textField)
bottomBar.addSubview(button)
#途中経過
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setUI()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func setUI(){
// Create UI Parts
// bottomBar
// L> textField
// L> button
let bottomBar = UIView(frame: CGRectMake(0, self.view.frame.height - 50, self.view.frame.size.width, 50))
bottomBar.backgroundColor = UIColor(red:0.85, green:0.85, blue:0.85, alpha:1.0)
let button = UIButton(frame: CGRectMake(0, 0, 80, 30))
button.backgroundColor = UIColor(red:0.25, green:0.60, blue:0.75, alpha:1.0)
button.setTitle("sumbit", forState: .Normal)
button.titleLabel?.font = UIFont(name: "Futura", size: 14)
button.setTitleColor(UIColor.whiteColor(), forState: .Normal)
button.layer.cornerRadius = 5.0;
let textField = UITextField(frame: CGRectMake(0, 0, self.view.frame.size.width * 0.7, 30))
textField.borderStyle = .RoundedRect
button.translatesAutoresizingMaskIntoConstraints = false
bottomBar.translatesAutoresizingMaskIntoConstraints = false
textField.translatesAutoresizingMaskIntoConstraints = false
// Add UI parts
view.addSubview(bottomBar)
bottomBar.addSubview(textField)
bottomBar.addSubview(button)
#Constrains追加
##まずはbottomBarからConstraintsを設定していきます。
bottomBarはViewに対してConstrainsをつけていきます。
- bottomBarLeading : 左設定します(Leading == Leftです。)
- bottomBarTrailing: 右設定します(Trailing == Rightです。)
- bottomBarBottom: 下位置を設定
- bottomBarWidth: 幅を設定します
- bottomBarHeight: 高さを設定します。
//bottomBarとUIView(スクリーンの関係性を示します)
//これがないと中のパーツの設定をした際、bottomBar自身が動いてしまいます。
let bottomBarLeading = NSLayoutConstraint(
item: bottomBar, //bottomBarの
attribute: .Leading, //左サイドに、(.Leftも可)
relatedBy: .Equal, //値はイコールで
toItem: view, //View(スクリーン)に対して
attribute: .Leading, //View(スクリーン)の左側から
multiplier: 1.0,
constant: 0 //0の位置に配置する
)
let bottomBarTrailing = NSLayoutConstraint(
item: bottomBar,
attribute: .Trailing, //(.Rightも可)
relatedBy: .Equal,
toItem: view,
attribute: .Trailing,
multiplier: 1.0,
constant: 0
)
// Cssの"bottom:0"的な感じです
let bottomBarConstraintBottom = NSLayoutConstraint(
item: bottomBar,
attribute: .Bottom,
relatedBy: .Equal,
toItem: self.view,
attribute: .Bottom,
multiplier: 1.0,
constant: 0
)
let bottomBarWidth = NSLayoutConstraint(
item: bottomBar, //bottomBarに対して
attribute: .Width, //Width Attributeを使用して
relatedBy: .Equal, //値の扱いはイコールで
toItem: nil, //幅を指定しているだけなので、対象のパーツはなし。よってnil
attribute: .NotAnAttribute, //対象パーツなしなので、NotAnAttribute
multiplier: 1.0, //multiplierする必要ないので1.0
constant: self.view.frame.size.width //数字入力じゃなくてサイズ取って来ましょう
)
let bottomBarHeight = NSLayoutConstraint(
item: bottomBar,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: 50 //bottomBar.frame.size.heightにするの忘れてました
)
##textFieldにConstraintsを設定していきます。
bottomBarに対して、textField位置の制約を追加していきます。
- textFieldCenterY : 垂直(縦方向)中央揃え設定します
- textFieldWidth: 幅設定します
- textFieldHeight: 高さ設定します
- textFieldLeading: 左位置を設定します
//******* textField Constraints *******
// Set Center Y to textField
let textFieldCenterY = NSLayoutConstraint(
item: textField,
attribute: .CenterY,
relatedBy: .Equal,
toItem: bottomBar,
attribute: .CenterY,
multiplier: 1.0,
constant: 0
)
let textFieldWidth = NSLayoutConstraint(
item: textField,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: textField.frame.size.width * 0.8
)
let textFieldHeight = NSLayoutConstraint(
item: textField,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: textField.frame.size.height
)
let textFieldLeading = NSLayoutConstraint(
item: textField,
attribute: .Left,
relatedBy: .Equal,
toItem: bottomBar,
attribute: .Left,
multiplier: 1.0,
constant: 20
)
let textFieldTop = NSLayoutConstraint(
item: textField,
attribute: .Top,
relatedBy: .Equal,
toItem: bottomBar,
attribute: .Top,
multiplier: 1,
constant: 10
)
#buttonnにConstraintsを設定していきます。
- buttonCenterY
- buttonWidth
- buttonHeight
- buttonTrailing
let buttonCenterY = NSLayoutConstraint(
item: button,
attribute: .CenterY,
relatedBy: .Equal,
toItem: bottomBar,
attribute: .CenterY,
multiplier: 1.0,
constant: 0
)
let buttonWidth = NSLayoutConstraint(
item: button,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: button.frame.size.width
)
let buttonHeight = NSLayoutConstraint(
item: button,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: button.frame.size.height
)
let buttonTrailing = NSLayoutConstraint(
item: button, // buttonの
attribute: .Leading, //左側を
relatedBy: .Equal,
toItem: textField, // textFieldの
attribute: .Trailing, // 右側から
multiplier: 1.0,
constant: 20 // 20サイズのところに配置
)
#最後にconstraintsを追加
さっき作成したConstraints達を追加していってください。
// Add Constraints
// buttonやtextFieldはbottomBarに対してのものなので、bottomBarに追加してください。
bottomBar.addConstraints([ buttonLeading, buttonWidth, buttonHeight, buttonCenterY])
bottomBar.addConstraints([textFieldCenterY, textFieldHeight, textFieldWidth,textFieldLeading])
// 見やすいようにaddConstraintsをパーツ別に分けています。
// bottomBarのConstraintsはviewに対してのものなのでviewへ。
self.view.addConstraints([bottomBarConstraintBottom, bottomBarWidth, bottomBarHeight, bottomBarLeading, bottomBarTrailing])
#最終形態
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setUI()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func setUI(){
// Create UI Parts
// bottomBar
// L> textField
// L> button
let bottomBar = UIView(frame: CGRectMake(0, self.view.frame.height - 50, self.view.frame.size.width, 50))
bottomBar.backgroundColor = UIColor(red:0.85, green:0.85, blue:0.85, alpha:1.0)
let button = UIButton(frame: CGRectMake(0, 0, self.view.frame.size.width * 0.2, 30))
button.backgroundColor = UIColor(red:0.25, green:0.60, blue:0.75, alpha:1.0)
button.setTitle("Sumbit", forState: .Normal)
button.titleLabel?.font = UIFont(name: "Futura", size: 14)
button.setTitleColor(UIColor.whiteColor(), forState: .Normal)
button.layer.cornerRadius = 5.0;
let textField = UITextField(frame: CGRectMake(0, 0, self.view.frame.size.width * 0.8, 30))
textField.borderStyle = .RoundedRect
button.translatesAutoresizingMaskIntoConstraints = false
bottomBar.translatesAutoresizingMaskIntoConstraints = false
textField.translatesAutoresizingMaskIntoConstraints = false
// Add UI parts
view.addSubview(bottomBar)
bottomBar.addSubview(textField)
bottomBar.addSubview(button)
let bottomBarWidth = NSLayoutConstraint(
item: bottomBar,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: self.view.frame.size.width
)
let bottomBarLeading = NSLayoutConstraint(
item: bottomBar,
attribute: .Leading,
relatedBy: .Equal,
toItem: view,
attribute: .Leading,
multiplier: 1.0,
constant: 0
)
let bottomBarTrailing = NSLayoutConstraint(
item: bottomBar,
attribute: .Trailing,
relatedBy: .Equal,
toItem: view,
attribute: .Trailing,
multiplier: 1.0,
constant: 0
)
let bottomBarHeight = NSLayoutConstraint(
item: bottomBar,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: 50
)
let bottomBarConstraintBottom = NSLayoutConstraint(
item: bottomBar,
attribute: .Bottom,
relatedBy: .Equal,
toItem: self.view,
attribute: .Bottom,
multiplier: 1.0,
constant: 0
)
//******* textField Constraints *******
// Set Center Y to textField
let textFieldCenterY = NSLayoutConstraint(
item: textField,
attribute: .CenterY,
relatedBy: .Equal,
toItem: bottomBar,
attribute: .CenterY,
multiplier: 1.0,
constant: 0
)
let textFieldWidth = NSLayoutConstraint(
item: textField,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: textField.frame.size.width * 0.8
)
let textFieldHeight = NSLayoutConstraint(
item: textField,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: textField.frame.size.height
)
let textFieldLeading = NSLayoutConstraint(
item: textField,
attribute: .Leading,
relatedBy: .Equal,
toItem: bottomBar,
attribute: .Leading,
multiplier: 1.0,
constant: 20
)
//******* Button Constraints *******
// Set Center Y to bottoBar
let buttonCenterY = NSLayoutConstraint(
item: button,
attribute: .CenterY,
relatedBy: .Equal,
toItem: bottomBar,
attribute: .CenterY,
multiplier: 1.0,
constant: 0
)
let buttonWidth = NSLayoutConstraint(
item: button,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: button.frame.size.width
)
let buttonHeight = NSLayoutConstraint(
item: button,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1.0,
constant: button.frame.size.height
)
let buttonLeading = NSLayoutConstraint(
item: button,
attribute: .Leading,
relatedBy: .Equal,
toItem: textField,
attribute: .Trailing,
multiplier: 1.0,
constant: 20
)
// Add Constraints
bottomBar.addConstraints([ buttonLeading, buttonWidth, buttonHeight, buttonCenterY])
bottomBar.addConstraints([textFieldCenterY, textFieldHeight, textFieldWidth,textFieldLeading])
self.view.addConstraints([bottomBarConstraintBottom, bottomBarWidth, bottomBarHeight, bottomBarLeading, bottomBarTrailing])
}
}
定数名変更したので、エラーあるかもです。エラー発見した場合やここのConstraintsいらないっていう場合はお手数ですが、コメントお願いします。
以上です。
最後までありがとうございました。