-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #216 from antoinelamy/feature/AutoSizing
Add automatic sizeThatFits computation for views
- Loading branch information
Showing
19 changed files
with
456 additions
and
72 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
language: objective-c | ||
osx_image: xcode11.2 | ||
osx_image: xcode11.5 | ||
|
||
cache: | ||
- bundler | ||
|
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
8 changes: 8 additions & 0 deletions
8
Example/PinLayoutSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>IDEDidComputeMac32BitWarning</key> | ||
<true/> | ||
</dict> | ||
</plist> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import UIKit | ||
|
||
class ContentService { | ||
static let shared = ContentService() | ||
|
||
private init() {} | ||
|
||
func fetchText(numberOfParagraph: Int = 1, completionHandler: ((Result<[String], Error>) -> Void)?) { | ||
URLSession.shared.dataTask(with: URL(string: "https://baconipsum.com/api/?type=all-meat¶s=\(numberOfParagraph)&start-with-lorem=1")!) { data, _, error in | ||
guard let data = data, error == nil, | ||
let paragraphs = try? JSONDecoder().decode([String].self, from: data) | ||
else { | ||
DispatchQueue.main.async { | ||
completionHandler?(Result<[String], Error>.failure(error!)) | ||
} | ||
return | ||
} | ||
|
||
DispatchQueue.main.async { | ||
completionHandler?(Result<[String], Error>.success(paragraphs)) | ||
} | ||
}.resume() | ||
} | ||
|
||
func fetchImage(width: Int, height: Int, completionHandler: ((Result<UIImage, Error>) -> Void)?) { | ||
URLSession.shared.dataTask(with: URL(string: "https://baconmockup.com/\(width)/\(height)")!) { data, _, error in | ||
guard let data = data, error == nil, | ||
let image = UIImage(data: data) | ||
else { | ||
DispatchQueue.main.async { | ||
completionHandler?(Result<UIImage, Error>.failure(error!)) | ||
} | ||
return | ||
} | ||
|
||
DispatchQueue.main.async { | ||
completionHandler?(Result<UIImage, Error>.success(image)) | ||
} | ||
}.resume() | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Foundation | ||
|
||
@propertyWrapper | ||
public struct Proxy<Value, EnclosingSelf> { | ||
private let keyPath: ReferenceWritableKeyPath<EnclosingSelf, Value> | ||
|
||
public init(_ keyPath: ReferenceWritableKeyPath<EnclosingSelf, Value>) { | ||
self.keyPath = keyPath | ||
} | ||
|
||
public var wrappedValue: Value { | ||
get { fatalError() } | ||
set { fatalError() } | ||
} | ||
|
||
public static subscript( | ||
_enclosingInstance observed: EnclosingSelf, | ||
wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Value>, | ||
storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Self> | ||
) -> Value { | ||
get { | ||
let storageValue = observed[keyPath: storageKeyPath] | ||
let value = observed[keyPath: storageValue.keyPath] | ||
return value | ||
} | ||
set { | ||
let storageValue = observed[keyPath: storageKeyPath] | ||
observed[keyPath: storageValue.keyPath] = newValue | ||
} | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
Example/PinLayoutSample/UI/Examples/AutoSizing/AutoSizingContainerView.swift
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import UIKit | ||
|
||
final class AutoSizingContainerView: UIView { | ||
private let imageView = UIImageView() | ||
private let firstTextLabel = UILabel() | ||
private let secondTextLabel = UILabel() | ||
|
||
private let margin: CGFloat = 10 | ||
|
||
@Proxy(\AutoSizingContainerView.imageView.image) | ||
var image: UIImage? { | ||
didSet { | ||
setNeedsLayout() | ||
} | ||
} | ||
|
||
@Proxy(\AutoSizingContainerView.firstTextLabel.text) | ||
var firstText: String? { | ||
didSet { | ||
setNeedsLayout() | ||
} | ||
} | ||
|
||
@Proxy(\AutoSizingContainerView.secondTextLabel.text) | ||
var secondText: String? { | ||
didSet { | ||
setNeedsLayout() | ||
} | ||
} | ||
|
||
init() { | ||
super.init(frame: CGRect.zero) | ||
configureView() | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
private func configureView() { | ||
imageView.clipsToBounds = true | ||
imageView.contentMode = .scaleAspectFill | ||
addSubview(imageView) | ||
|
||
firstTextLabel.numberOfLines = 0 | ||
firstTextLabel.backgroundColor = UIColor.orange.withAlphaComponent(0.3) | ||
addSubview(firstTextLabel) | ||
|
||
secondTextLabel.numberOfLines = 0 | ||
secondTextLabel.backgroundColor = UIColor.green.withAlphaComponent(0.3) | ||
addSubview(secondTextLabel) | ||
} | ||
|
||
override func layoutSubviews() { | ||
super.layoutSubviews() | ||
performLayout() | ||
} | ||
|
||
private func performLayout() { | ||
imageView.pin.top().horizontally().sizeToFit(.width).margin(margin) | ||
firstTextLabel.pin.below(of: imageView).horizontally().sizeToFit(.width).margin(margin) | ||
secondTextLabel.pin.below(of: firstTextLabel).horizontally().sizeToFit(.width).margin(margin) | ||
} | ||
|
||
override func sizeThatFits(_ size: CGSize) -> CGSize { | ||
autoSizeThatFits(size, layoutClosure: performLayout) | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
Example/PinLayoutSample/UI/Examples/AutoSizing/AutoSizingView.swift
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import UIKit | ||
import PinLayout | ||
|
||
final class AutoSizingView: UIView { | ||
private let scrollView = UIScrollView() | ||
private let containerView = AutoSizingContainerView() | ||
|
||
private let margin: CGFloat = 30 | ||
|
||
init() { | ||
super.init(frame: CGRect.zero) | ||
configureView() | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
private func configureView() { | ||
backgroundColor = .white | ||
|
||
scrollView.alwaysBounceVertical = true | ||
addSubview(scrollView) | ||
|
||
containerView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.3) | ||
scrollView.addSubview(containerView) | ||
} | ||
|
||
func updateImage(_ image: UIImage?) { | ||
containerView.image = image | ||
setNeedsLayout() | ||
} | ||
|
||
func updateTexts(firstText: String?, secondText: String?) { | ||
containerView.firstText = firstText | ||
containerView.secondText = secondText | ||
setNeedsLayout() | ||
} | ||
|
||
override func layoutSubviews() { | ||
super.layoutSubviews() | ||
performLayout() | ||
didPerformLayout() | ||
} | ||
|
||
private func performLayout() { | ||
scrollView.pin.all() | ||
containerView.pin.top(margin).horizontally(margin).sizeToFit(.width) | ||
} | ||
|
||
private func didPerformLayout() { | ||
scrollView.contentSize = CGSize(width: bounds.width, height: containerView.frame.maxY + margin) | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
Example/PinLayoutSample/UI/Examples/AutoSizing/AutoSizingViewController.swift
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import UIKit | ||
|
||
class AutoSizingViewController: UIViewController { | ||
private var mainView: AutoSizingView { | ||
return self.view as! AutoSizingView | ||
} | ||
|
||
override func loadView() { | ||
self.view = AutoSizingView() | ||
} | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
configureNavigationBar() | ||
} | ||
|
||
override func viewWillAppear(_ animated: Bool) { | ||
super.viewWillAppear(animated) | ||
randomizeContent() | ||
} | ||
|
||
private func configureNavigationBar() { | ||
navigationItem.title = "AutoSizing" | ||
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Randomize", style: .plain, target: self, action: #selector(randomizeContent)) | ||
} | ||
|
||
@objc | ||
private func randomizeContent() { | ||
ContentService.shared.fetchText(numberOfParagraph: 2) { [weak self] (result) in | ||
guard let strongSelf = self, case let .success(paragraphs) = result else { return } | ||
strongSelf.mainView.updateTexts(firstText: paragraphs[0], secondText: paragraphs[1]) | ||
} | ||
|
||
ContentService.shared.fetchImage(width: Int.random(in: 200..<500), height: Int.random(in: 200..<500)) { [weak self] (result) in | ||
guard let strongSelf = self, case let .success(image) = result else { return } | ||
strongSelf.mainView.updateImage(image) | ||
} | ||
} | ||
} |
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
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
Oops, something went wrong.