Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Empty State表示共通化の事例 / Case of empty state commo...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
kentaro
December 18, 2018
Technology
3.9k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Empty State表示共通化の事例 / Case of empty state commonization
potatotips #57の資料です。
https://potatotips.connpass.com/event/109263/
kentaro
December 18, 2018
Other Decks in Technology
See All in Technology
Atlassian Cloudサポート業務でのAIエージェント活用事例
smt7174
0
220
セキュリティ研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
32
27k
AIは実装を速くする。では、私たちは何を今作るべきか?-立場を越えてリリースに向き合ったチーム開発の実践 / 20260801 Hiromi Nakaya and Naoki Takahashi
shift_evolve
PRO
3
180
AI驚き屋発見器
yama3133
2
390
ここは地獄!つらい朝会を体験することで、チームとしてのより良い振る舞いに気づくワークショップ / The stand-up meeting from hell in the game industry
scrummasudar
0
520
WEBフロントエンド研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
2
900
AI エージェント時代のデジタルアイデンティティ
fujie
2
1.3k
NetBoxを利用した作業効率化の試み_NetDevNight4
tnoha
0
420
plamo-3-translateの開発
pfn
PRO
0
240
MIRU 2026 チュートリアル
keisuke198619
0
410
書籍セキュアAPIについて
riiimparm
0
400
もう一度考える SRE チームの作り方・育て方 / Rethinking SRE #1: Building and Growing SRE Teams
rrreeeyyy
4
620
Featured
See All Featured
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
500
AI: The stuff that nobody shows you
jnunemaker
PRO
9
860
30 Presentation Tips
portentint
PRO
1
360
Abbi's Birthday
coloredviolet
3
8.9k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
410
The browser strikes back
jonoalderson
0
1.4k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Typedesign – Prime Four
hannesfritz
42
3.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
2
3.7k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Mobile First: as difficult as doing things right
swwweet
225
10k
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ͰָΛͯ͠ ྗΛೖΕΔ͖ͱ͜Ζʹ ྗͰ͖ΔΑ͏ʹͳΔͱϋοϐʔ