Speaker Deck
Speaker Deck Pro
Sign in
Sign up
for free
Empty State表示共通化の事例 / Case of empty state commonization
kentaro
December 18, 2018
Technology
2
2.7k
Empty State表示共通化の事例 / Case of empty state commonization
potatotips #57の資料です。
https://potatotips.connpass.com/event/109263/
kentaro
December 18, 2018
Tweet
Share
Other Decks in Technology
See All in Technology
hsano
0
120
kakka
0
3.3k
yosuke_matsuura
PRO
0
3.1k
shomaekawa
2
920
unifa_dev
0
280
satoshirobatofujimoto
0
110
hamadakoji
0
1.1k
sakon310
4
4.2k
hamadakoji
2
470
kurotanshi
0
170
torisoup
0
260
jakalada
1
260
Featured
See All Featured
akmur
252
19k
morganepeng
92
13k
paulrobertlloyd
71
1.4k
malarkey
119
16k
skipperchong
7
660
maltzj
500
36k
trishagee
20
2k
davidbonilla
69
3.5k
sachag
446
36k
jeffersonlam
328
15k
dougneiner
55
5.4k
3n
163
22k
Transcript
&NQUZ4UBUFදࣔڞ௨Խͷࣄྫ QPUBUPUJQT,FOUBSP5BHVDIJ !LFOLFOLFO@
֓ཁ ϧʔϧܾΊ ࣮ʹ͍ͭͯ Ξ δ Σ ϯ
μ
֓ཁ
&NQUZ4UBUFͷදࣔΛ౷Ұͨ͠ Կ Λ ͠ ͨ ͷ ͔
ը໘࡞࣌ʹσβΠϯɾ࣮͞Ε͍ͯͨ ը໘ʹΑͬͯද͕ࣔόϥόϥ σβΠϯɾ࣮Λʮߟ͑Δʯ͕ൃੜ ͳ ͥ ͬ ͨ ͷ ͔
C F G P S F
B G U F S
w ΞϓϦͷ&NQUZ4UBUFද͕ࣔ౷Ұ͞Εͨ w ίετݮʢاըɾσβΠϯɾ࣮ʣ Կ ͕ ಘ Β Ε ͨ
ͷ ͔
ϧʔϧܾΊ
σβΠφʔͱ૬ஊ ༷ɾσβΠϯͷϧʔϧΛܾΊͨ ֓ ཁ
จݴΛදࣔ͢Δ͚ͩʢ࠶ݕࡧͷػೳ͚ͭͳ͍ʣ $73Λ͍ͬͯͳ͍ γϯϓϧͳ༷Ͱ0, ༷
දࣔ͢ΔཁૉʹରԠͨ͠จݴΛఆΊΔ ༧ใ ʮ༧ใ͋Γ·ͤΜʯ จ ݴ
w ϑΥϯτͷαΠζɾΧϥʔΛ౷Ұ w 7JFXͷதԝʹϥϕϧΛஔ σ β Π ϯ
ϧʔϧFTBʹ·ͱΊͯνʔϜʹڞ༗ ʢશࣾһӾཡՄೳʣ ʢΤϯδχΞ͚ʹJ04࣮·ͱΊهࡌʣ υ Ω ϡ ϝ ϯ τ Խ
࣮
protocolͱenumΛͬͯ ൚༻తʹར༻Ͱ͖ΔΑ͏ʹ࣮͢Δ ํ
FOVNͰදࣔཁૉΛදݱ ରԠ͢Δจݴఆٛ จ ݴ
/// empty stateΛఆٛ͢Δenum enum EmptyState { /// ༧ case reservation
/// ςʔϒϧ case table // ʢଞলུʣ /// λΠτϧ var title: String { switch self { case .reservation: return NSLocalizedString("key_of_reservation", comment: "") case .table: return NSLocalizedString("key_of_table", comment: “") // ʢଞলུʣ } } }
QSJWBUFͰ࣮ ֎͔Β༨ܭͳૢ࡞ͤ͞ͳ͍ ݟ͕ͨ౷Ұ͞ΕΔ W J F X
/// empty state༻ͷView private final class EmptyStateView: UIView { ///
λΠτϧϥϕϧ private let titleLabel: UILabel = { let titleLabel = UILabel() // ϥϕϧͷઃఆ return titleLabel }() init(_ state: EmptyState) { super.init(frame: .zero) setup(with: state) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } /// ηοτΞοϓΛ͢Δ private func setup(with state: EmptyState) { titleLabel.text = state.title addSubview(titleLabel) titleLabel.edges(equalTo: self) } }
֎͔Β͍ͭ͜Λ͍͡Δ &NQUZ4UBUF7JFXͱಉ͡ϑΝΠϧʹ࣮ ) P M E F S
/// empty stateΛදࣔ͢ΔViewͷϗϧμʔ final class EmptyStateHolder { /// ຊϓϩύςΟܦ༝ͰviewͷisHiddenΛ֎͔Βηοτ͢Δ var
isHidden = false { didSet { view.isHidden = isHidden } } /// empty stateΛදࣔ͢ΔView /// /// fileprivateʹͯ͠༨ܭͳPropertyΛϑΝΠϧ֎͔Βૢ࡞ͤ͞ͳ͍ /// ͱ͢Δ͜ͱͰݟ͕ͨΞϓϦͰ౷Ұ͞ΕΔ͜ͱΛ୲อ fileprivate let view: EmptyStateView /// state͔ΒࣗΛੜ͢Δ /// 1ՕॴͰෳλΠϓͷEmptyStateΛग़͢ཁ͕݅ͳ͍લఏͷ࣮ /// /// - Parameter state: EmptyState init(_ state: EmptyState) { view = EmptyStateView(state) } }
ԼهΛࢀߟʹ&EHFʹର੍ͯ͠Λ͚ͭΔ 6*7JFXͷFYUFOTJPOΛ࣮ IUUQTTQFBLFSEFDLDPNLBNFJLFGBSFXFMMTOBQLJU ิ ɿ 7 J F X
ͷ F Y U F O T J P O
extension UIView { /// ࣗͷEdgeʹର੍ͯ͠Λ͚ͭΔ /// /// - Parameters: ///
- view: ੍ͷج४ͱͳΔview /// - offset: ੍ (σϑΥϧτ: .zero ) func edges(equalTo view: UIView, offset: UIEdgeInsets = .zero) { translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ topAnchor.constraint(equalTo: view.topAnchor, constant: offset.top), bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -offset.bottom), leftAnchor.constraint(equalTo: view.leftAnchor, constant: offset.left), rightAnchor.constraint(equalTo: view.rightAnchor, constant: -offset.right) ]) } }
ڞ௨Խ༻ͷQSPUPDPMΛ࡞ Q S P U P D P M
// MARK: - ڞ௨Խ༻ϓϩτίϧ /// empty stateදࣔϓϩτίϧ protocol EmptyStateDisplayable where
Self: UIResponder { /// empty stateΛදࣔ͢ΔViewͷϗϧμʔ var emptyStateHolder: EmptyStateHolder { get } /// emptyStateViewΛadd͢Δ func addEmptyStateView() }
6*7JFX$POUSPMMFSɾ6*7JFX ͦΕͧΕσϑΥϧτ࣮ΛՃ ʢجຊˢΛݺͿ͚ͩʣ Q S P U P D P
M F Y U F O T J P O
// MARK: - UIViewControllerͷ߹ extension EmptyStateDisplayable where Self: UIViewController {
/// emptyStateViewΛviewʹaddSubview͢Δ func addEmptyStateView() { view.addSubview(emptyStateHolder.view) emptyStateHolder.view.edges(equalTo: view) } } // MARK: - UIViewͷ߹ extension EmptyStateDisplayable where Self: UIView { /// emptyStateViewΛࣗʹaddSubview͢Δ func addEmptyStateView() { addSubview(emptyStateHolder.view) emptyStateHolder.view.edges(equalTo: self) } }
/// ར༻ଆͷ࣮ྫ /// EmptyStateDisplayableʹ४ڌͤ͞Δ final class SampleViewController: UIViewController, EmptyStateDisplayable {
/// EmptyStateDisplayableͷϓϩύςΟ /// ରԠ͢ΔEmptyState(enum)͔ΒॳظԽ let emptyStateHolder = EmptyStateHolder(.reservation) override func viewDidLoad() { super.viewDidLoad() // EmptyStateDisplayableͷϝιουΛݺEmptyStateView͕addSubView͞ΕΔ addEmptyStateView() // EmptyStateΛදࣔ͢Δ݅ʹ߹ΘͤͯemptyStateHolder.isHiddenʹΛηοτ emptyStateHolder.isHidden = false } }
&NQUZ4UBUFͰָΛͯ͠ ྗΛೖΕΔ͖ͱ͜Ζʹ ྗͰ͖ΔΑ͏ʹͳΔͱϋοϐʔ