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
struct InputView: View { | |
let title: String | |
var placeholder: String = "" | |
let value: Binding<String> | |
var body: some View { | |
VStack { | |
HStack { | |
Text(title) | |
.font(.subheadline) |
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
struct ContentView: View { | |
@StateObject var viewModel = ViewModel(package: .makeExample()) | |
var body: some View { | |
ScrollView { | |
VStack(spacing: 16) { | |
Text("Recipient") | |
.font(.headline) | |
InputView(title: "First name", | |
value: $viewModel.recipientFirstName) |
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 Package: NSObject { | |
@objc dynamic var recipient = Person() | |
@objc dynamic var sender = Person() | |
@objc dynamic var contents = [PackageContent]() | |
} | |
final class Person: NSObject { | |
@objc dynamic var firstName: String = "" | |
@objc dynamic var lastName: String = "" | |
@objc dynamic var postalAddress = CNPostalAddress() |
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
// MARK: View | |
struct PackageCombineModelView: View { | |
@StateObject var viewModel: ViewModel | |
var body: some View { | |
Form { | |
TextField("First name", text: $viewModel.firstName) | |
Text(viewModel.modelDescription) | |
} |
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
// MARK: View | |
struct PackageKVOModelView: View { | |
@StateObject var viewModel: ViewModel | |
var body: some View { | |
Form { | |
TextField("First name", text: $viewModel.firstName) | |
Text(viewModel.modelDescription) | |
} |
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
struct ImageScaler { | |
static func scaleToFill(_ image: UIImage, in targetSize: CGSize, from fromRect: CGRect = .zero) -> UIImage { | |
let rect = fromRect.isEmpty ? CGRect(origin: .zero, size: image.size) : fromRect | |
let scaledRect = rect.scaled(toFillSize: targetSize) | |
return scale(image, fromRect: scaledRect, targetSize: targetSize) | |
} | |
private static func scale(_ image: UIImage, fromRect: CGRect = .zero, targetSize: CGSize) -> UIImage { | |
let renderer = UIGraphicsImageRenderer(size: targetSize) | |
return renderer.image { context in |
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
extension CGRect { | |
func scaled(toFillSize targetSize: CGSize) -> CGRect { | |
var scaledRect = self | |
switch (size.aspect, targetSize.aspect) { | |
case (.portrait, .portrait), (.portrait, .square): | |
scaledRect.size.height = width / targetSize.aspectRatio | |
scaledRect.size.width = width | |
if scaledRect.height > height { | |
scaledRect.size = size | |
} |
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
extension CGSize { | |
enum Aspect { | |
case portrait, landscape, square | |
} | |
var aspect: Aspect { | |
switch width / height { | |
case 1.0: | |
return .square | |
case 1.0...: | |
return .landscape |
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
private static func scale(_ image: UIImage, fromRect: CGRect = .zero, targetSize: CGSize) -> UIImage { | |
let renderer = UIGraphicsImageRenderer(size: targetSize) | |
return renderer.image { context in | |
// UIImage and CGContext coordinates are flipped. | |
var transform = CGAffineTransform(translationX: 0.0, y: targetSize.height) | |
transform = transform.scaledBy(x: 1, y: -1) | |
context.cgContext.concatenate(transform) | |
// UIImage -> cropped CGImage | |
let makeCroppedCGImage: (UIImage) -> CGImage? = { image in | |
guard let cgImage = image.cgImage else { return nil } |
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
var transform = CGAffineTransform(translationX: 0.0, y: targetSize.height) | |
transform = transform.scaledBy(x: 1, y: -1) | |
context.cgContext.concatenate(transform) |