Skip to content

Commit 6439f35

Browse files
committed
Added onboarding controller. Fixed avatar.
1 parent 1ffdf13 commit 6439f35

File tree

5 files changed

+242
-1
lines changed

5 files changed

+242
-1
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// The MIT License (MIT)
2+
// Copyright © 2021 Ivan Vorobei ([email protected])
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy
5+
// of this software and associated documentation files (the "Software"), to deal
6+
// in the Software without restriction, including without limitation the rights
7+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the Software is
9+
// furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in all
12+
// copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
// SOFTWARE.
21+
22+
#if canImport(UIKit) && (os(iOS))
23+
import UIKit
24+
import SparrowKit
25+
26+
open class NativeOnboardingController: NativeHeaderController {
27+
28+
// MARK: - Data
29+
30+
private let items: [NativeOnboardingItem]
31+
private var itemViews: [NativeOnboardingItemView] = []
32+
33+
// MARK: - Init
34+
35+
public init(
36+
iconImage: UIImage?,
37+
title: String,
38+
subtitle: String,
39+
items: [NativeOnboardingItem]
40+
) {
41+
self.items = items
42+
super.init(image: iconImage, title: title, subtitle: subtitle)
43+
}
44+
45+
public required init?(coder: NSCoder) {
46+
fatalError("init(coder:) has not been implemented")
47+
}
48+
49+
// MARK: - Lifecycle
50+
51+
open override func viewDidLoad() {
52+
super.viewDidLoad()
53+
if #available(iOS 13.0, *) {
54+
self.view.backgroundColor = .systemBackground
55+
} else {
56+
view.backgroundColor = .white
57+
}
58+
itemViews = items.map({ NativeOnboardingItemView(item: $0) })
59+
scrollView.addSubviews(itemViews)
60+
}
61+
62+
// MARK: - Layout
63+
64+
open override func viewDidLayoutSubviews() {
65+
super.viewDidLayoutSubviews()
66+
var currentYPosition = headerView.frame.maxY + NativeLayout.Spaces.default_double
67+
for (_, itemView) in itemViews.enumerated() {
68+
itemView.setWidthAndFit(width: scrollView.readableWidth)
69+
itemView.setXCenter()
70+
itemView.frame.origin.y = currentYPosition
71+
currentYPosition = itemView.frame.maxY + NativeLayout.Spaces.default_half
72+
}
73+
scrollView.contentSize = .init(width: scrollView.frame.width, height: itemViews.last?.frame.maxY ?? .zero)
74+
}
75+
76+
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
77+
for itemView in itemViews {
78+
let progress = progressForItemView(itemView)
79+
itemView.setProgress(progress)
80+
}
81+
}
82+
83+
private func progressForItemView(_ itemView: NativeOnboardingItemView) -> CGFloat {
84+
let offsetY = scrollView.contentOffset.y + scrollView.safeAreaInsets.top + scrollView.frame.height - scrollView.safeAreaInsets.bottom
85+
let correction: CGFloat = NativeLayout.Spaces.Scroll.bottom_inset_reach_end
86+
let topSafeArea = scrollView.safeAreaInsets.top + correction
87+
let startPosition = itemView.frame.origin.y + topSafeArea
88+
let progress = (offsetY - startPosition) / itemView.frame.height
89+
if progress < .zero { return .zero }
90+
if progress > 1 { return 1 }
91+
return progress
92+
}
93+
}
94+
#endif
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// The MIT License (MIT)
2+
// Copyright © 2021 Ivan Vorobei ([email protected])
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy
5+
// of this software and associated documentation files (the "Software"), to deal
6+
// in the Software without restriction, including without limitation the rights
7+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the Software is
9+
// furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in all
12+
// copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
// SOFTWARE.
21+
22+
#if canImport(UIKit) && (os(iOS))
23+
import UIKit
24+
import SparrowKit
25+
26+
public class NativeOnboardingItem {
27+
28+
let iconImage: UIImage
29+
let title: String
30+
let description: String
31+
32+
public init(iconImage: UIImage, title: String, description: String) {
33+
self.iconImage = iconImage
34+
self.title = title
35+
self.description = description
36+
}
37+
}
38+
#endif
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// The MIT License (MIT)
2+
// Copyright © 2021 Ivan Vorobei ([email protected])
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy
5+
// of this software and associated documentation files (the "Software"), to deal
6+
// in the Software without restriction, including without limitation the rights
7+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the Software is
9+
// furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in all
12+
// copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
// SOFTWARE.
21+
22+
#if canImport(UIKit) && (os(iOS))
23+
import UIKit
24+
import SparrowKit
25+
26+
public class NativeOnboardingItemView: SPView {
27+
28+
// MARK: - Views
29+
30+
let iconView = SPImageView().do {
31+
$0.contentMode = .scaleAspectFit
32+
}
33+
34+
let titleLabel = SPLabel().do {
35+
$0.font = .preferredFont(forTextStyle: .title3, weight: .semibold)
36+
if #available(iOS 13.0, *) {
37+
$0.textColor = .label
38+
} else {
39+
$0.textColor = .black
40+
}
41+
$0.numberOfLines = .zero
42+
}
43+
44+
let descriptionLabel = SPLabel().do {
45+
$0.font = .preferredFont(forTextStyle: .body)
46+
if #available(iOS 13.0, *) {
47+
$0.textColor = .secondaryLabel
48+
} else {
49+
$0.textColor = .black
50+
}
51+
$0.numberOfLines = .zero
52+
}
53+
54+
// MARK: - Init
55+
56+
init(item: NativeOnboardingItem) {
57+
super.init()
58+
iconView.image = item.iconImage
59+
titleLabel.text = item.title
60+
descriptionLabel.text = item.description
61+
}
62+
63+
required init?(coder aDecoder: NSCoder) {
64+
fatalError("init(coder:) has not been implemented")
65+
}
66+
67+
public override func commonInit() {
68+
super.commonInit()
69+
backgroundColor = .clear
70+
roundCorners(radius: NativeLayout.Spaces.default_less)
71+
layoutMargins = .init(horizontal: NativeLayout.Spaces.default_more, vertical: NativeLayout.Spaces.default_more)
72+
addSubviews(iconView, titleLabel, descriptionLabel)
73+
}
74+
75+
// MARK: - Layout
76+
77+
public override func layoutSubviews() {
78+
super.layoutSubviews()
79+
iconView.frame = .init(side: 42)
80+
iconView.frame.origin.y = layoutMargins.top
81+
iconView.frame.origin.x = layoutMargins.left
82+
83+
let labelWidth = layoutWidth - iconView.frame.width - NativeLayout.Spaces.default
84+
85+
titleLabel.layoutDynamicHeight(width: labelWidth)
86+
titleLabel.setMaxXToSuperviewRightMargin()
87+
titleLabel.frame.origin.y = layoutMargins.top
88+
89+
descriptionLabel.layoutDynamicHeight(width: labelWidth)
90+
descriptionLabel.frame.origin.x = titleLabel.frame.origin.x
91+
descriptionLabel.frame.origin.y = titleLabel.frame.maxY + NativeLayout.Spaces.step
92+
}
93+
94+
public override func sizeThatFits(_ size: CGSize) -> CGSize {
95+
layoutSubviews()
96+
return .init(width: size.width, height: descriptionLabel.frame.maxY + layoutMargins.bottom)
97+
}
98+
99+
// MARK: - Actions
100+
101+
func setProgress(_ value: CGFloat) {
102+
if #available(iOS 13.0, *) {
103+
self.backgroundColor = .secondarySystemBackground.alpha(1 - value)
104+
}
105+
}
106+
}
107+
#endif

Sources/NativeUIKit/Table/LargeHeader/NativeLargeHeaderItem.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ open class NativeLargeHeaderItem: SPDiffableItem, SPDiffableItemActionable {
3232
open var actionTitle: String?
3333
open var action: Action?
3434

35-
public init(id: String? = nil, title: String, actionTitle: String?, action: Action? = nil) {
35+
public init(id: String? = nil, title: String, actionTitle: String? = nil, action: Action? = nil) {
3636
self.title = title
3737
self.actionTitle = actionTitle
3838
self.action = action

Sources/NativeUIKit/Views/NativeAvatarView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ open class NativeAvatarView: SPView {
4343
public lazy var avatarButton = SPButton().do {
4444
$0.imageView?.contentMode = .scaleAspectFill
4545
$0.layer.masksToBounds = true
46+
$0.contentVerticalAlignment = .fill
47+
$0.contentHorizontalAlignment = .fill
4648
}
4749

4850
public lazy var placeholderButton = SPDimmedButton().do {

0 commit comments

Comments
 (0)