設定風画面を簡単に構築できる Eureka という有名なiOSライブラリ。
UI系のライブラリはあまり使いたくないんですが、これはわりかし使ってます。
このライブラリで、Section の Header / Footer の文字色を気軽に変更したかったのですが思ったより手軽にできなかったので記事にしておきます。
環境
Xcode | iOS | Swift | Eureka |
---|---|---|---|
10.1 | 12.1 | 4.2 | 4.3.1 |
Eureka は Carthage 経由で導入
前提
- この
もじれつ
の文字色を変えたい
form +++ Section(footer: "もじれつ")
- 新たなUIViewクラス/IBファイルを作らず済ませたい (精神衛生上)
ちなみに独自クラスを用意する場合、下記のようにします。詳しくは README で。
Section() { section in
// xib ファイルから使う場合
section.header = HeaderFooterView<MyHeaderNibFile>(.nibFile(name: "MyHeaderNibFile", bundle: nil))
// コードから使う場合
section.header = HeaderFooterView<MyCustomUIView>(.class)
}
- Autolayout を使用して高さ可変にしたい
コード
import Eureka
extension Section {
convenience init(colorChangeableFooter: String) {
self.init { section in
var footer = HeaderFooterView<UIView>(.class)
footer.height = { UITableView.automaticDimension }
footer.onSetupView = { view, _ in
// 解説1
if let label = view.subviews.compactMap({ $0 as? UILabel }).first {
label.text = colorChangeableFooter
return
}
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false // 解説2
label.textColor = .white
label.text = colorChangeableFooter
label.font = UIFont.systemFont(ofSize: 13)
label.numberOfLines = 0
view.addSubview(label)
view.topAnchor.constraint(equalTo: label.topAnchor, constant: -8).isActive = true
view.bottomAnchor.constraint(equalTo: label.bottomAnchor, constant: 8).isActive = true
view.leftAnchor.constraint(equalTo: label.leftAnchor, constant: -15).isActive = true
view.rightAnchor.constraint(equalTo: label.rightAnchor, constant: 15).isActive = true
}
section.footer = footer
}
}
var colorChangeableFooterLabel: UILabel? {
return self.footer?.viewForSection(self, type: .footer)?.subviews.compactMap({ $0 as? UILabel }).first
}
}
// 使用したい箇所で
form +++ Section(colorChangeableFooter: "文字列")
// 色を変更する時 (該当Sectionインスタンスが section だとして)
section.colorChangeableFooterLabel?.textColor = .red
解説
1. onSetupView は複数回呼ばれる
複数回呼ばれる可能性があるのに何度もインスタンス生成して addSubview
していたら良くないので、
subviews
にあるかを確認してます。
2. Autoresizing Mask と Auto Layout
translatesAutoresizingMaskIntoConstraints
を false
にしとかないと、Autoresizing Mask の制約が勝手に Auto Layout の制約に変換されてしまって、うまくいきません。
これに気づくのに時間がかかりました。
3. その他
新たな UIView 継承クラスを作りたくないがためにこんなことをしていますが、本来 onSetupView
内で addSubview
とかをするの自体があんまりよろしくないと思います。(色や文字の変更などをすべき場所。)
今回はただ文字色を変更したいだけだったのでこのようにしましたが、記事を書いといてなんですが独自クラスを用意したほうが良いと思います。