Last active
September 15, 2022 18:43
-
-
Save rolandleth/f1264fa7032570526ed01d0ab63988d6 to your computer and use it in GitHub Desktop.
SwiftUI influences in UIKit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class VStack: UIStackView { | |
init(alignment: UIStackView.Alignment = .fill, spacing: CGFloat = 10, _ arrangedViews: UIView...) { | |
super.init(frame: .zero) | |
axis = .vertical | |
self.alignment = alignment | |
self.spacing = spacing | |
distribution = .fill | |
arrangedViews.forEach(addArrangedSubview) | |
} | |
required init(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
} | |
class HStack: UIStackView { | |
init(alignment: UIStackView.Alignment = .fill, spacing: CGFloat = 10, _ arrangedViews: UIView...) { | |
super.init(frame: .zero) | |
axis = .horizontal | |
self.alignment = alignment | |
self.spacing = spacing | |
distribution = .fill | |
arrangedViews.forEach(addArrangedSubview) | |
} | |
required init(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
} | |
final class Spacer: UIView { | |
init() { | |
super.init(frame: .zero) | |
autoresizingMask = [.flexibleWidth, .flexibleHeight] | |
// These might not be needed, but in case spacers don't work as expected, give them a try. | |
// The idea is that a `Spacer` has the lowest priority in hugging, since it doesn't care if it doesn't hug its content (it has none). | |
// A `Spacer` also should stop being compressed when other views would stop hugging. | |
// setContentHuggingPriority(.init(rawValue: 1), for: .vertical) | |
// setContentHuggingPriority(.init(rawValue: 1), for: .horizontal) | |
// | |
// setContentCompressionResistancePriority(.init(rawValue: UILayoutPriority.defaultLow.rawValue - 1), for: .vertical) | |
// setContentCompressionResistancePriority(.init(rawValue: UILayoutPriority.defaultLow.rawValue - 1), for: .horizontal) | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final class ViewController: UIViewController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
view.backgroundColor = .secondarySystemFill | |
let image = UIImageView(image: UIImage(named: "pic")) | |
image.contentMode = .scaleAspectFill | |
image.clipsToBounds = true | |
image.translatesAutoresizingMaskIntoConstraints = false | |
let nameLabel = UILabel() | |
nameLabel.font = UIFont.preferredFont(forTextStyle: .title1) | |
nameLabel.text = "Yosemite" | |
let infoLabel = UILabel() | |
infoLabel.font = UIFont.italicSystemFont( | |
ofSize: UIFont.preferredFont(forTextStyle: .caption1).pointSize) | |
infoLabel.text = "First climbed in: 1907" | |
let detailsStack = VStack( | |
spacing: 4, | |
detailsRow(labelText: "Difficulty:", valueText: "Hard"), | |
detailsRow(labelText: "Annual attempts:", valueText: "1452"), | |
detailsRow(labelText: "Monthly successful attempts:", valueText: "12") | |
) | |
detailsStack.translatesAutoresizingMaskIntoConstraints = false | |
let v = UIView() | |
v.translatesAutoresizingMaskIntoConstraints = false | |
v.backgroundColor = .blue | |
let content = VStack( | |
spacing: 16, | |
image, | |
HStack( | |
alignment: .lastBaseline, | |
nameLabel, | |
Spacer(), | |
infoLabel | |
), | |
HStack( | |
detailsStack, | |
VStack( | |
Spacer(), | |
HStack( | |
v, | |
Spacer() | |
) | |
) | |
), | |
HStack( | |
viewRow(number: 97, icon: "paperplane", text1: "Bird", text2: "species"), | |
Spacer(), | |
viewRow(number: 20, icon: "eyes", text1: "Breathtaking", text2: "views"), | |
Spacer(), | |
viewRow(number: 12, icon: "arrow.up", text1: "Oak", text2: "species") | |
), | |
Spacer() | |
) | |
content.translatesAutoresizingMaskIntoConstraints = false | |
view.addSubview(content) | |
NSLayoutConstraint.activate([ | |
content.topAnchor.constraint(equalTo: view.topAnchor), | |
content.bottomAnchor.constraint(equalTo: view.bottomAnchor), | |
content.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), | |
content.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16), | |
image.heightAnchor.constraint(equalToConstant: 100), | |
detailsStack.widthAnchor.constraint(equalToConstant: 250), | |
v.heightAnchor.constraint(equalToConstant: 20), | |
v.widthAnchor.constraint(equalToConstant: 100), | |
]) | |
} | |
private func detailsRow(labelText: String, valueText: String) -> UIView { | |
let label = UILabel() | |
label.font = UIFont.preferredFont(forTextStyle: .caption1) | |
label.text = labelText | |
let value = UILabel() | |
value.font = label.font | |
value.text = valueText | |
return HStack( | |
label, | |
Spacer(), | |
value | |
) | |
} | |
private func viewRow(number: Int, icon: String, text1: String, text2: String) -> UIView { | |
let numberLabel = UILabel() | |
numberLabel.font = UIFont.boldSystemFont(ofSize: UIFont.preferredFont(forTextStyle: .title1).pointSize) | |
numberLabel.text = "\(number)" | |
let text1Label = UILabel() | |
text1Label.font = UIFont.preferredFont(forTextStyle: .caption1) | |
text1Label.text = text1 | |
let text2Label = UILabel() | |
text2Label.font = text1Label.font | |
text2Label.text = text2 | |
let image = UIImage(systemName: icon, | |
withConfiguration: UIImage.SymbolConfiguration(font: text1Label.font))? | |
.withRenderingMode(.alwaysOriginal) | |
let imageView = UIImageView(image: image) | |
imageView.contentMode = .scaleAspectFit | |
return HStack( | |
alignment: .lastBaseline, | |
numberLabel, | |
VStack( | |
spacing: 0, | |
HStack( | |
spacing: 2, | |
imageView, | |
text1Label, | |
Spacer() | |
), | |
text2Label | |
) | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the example's output: