Add auto layout utilities

This commit is contained in:
Niels Andriesse 2019-09-20 16:47:27 +10:00
parent 0a65fcbd89
commit d9b11e35d6
3 changed files with 75 additions and 35 deletions

View File

@ -569,6 +569,7 @@
B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; };
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
B885D5F4233491AB00EE0D8E /* DeviceLinkingModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */; };
B885D5F62334A32100EE0D8E /* UIView+Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */; };
B891105C2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B891105E2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B891105F2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
@ -1373,6 +1374,7 @@
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = "<group>"; };
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModal.swift; sourceTree = "<group>"; };
B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = "<group>"; };
B891105B2320872800F15FCC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = "<group>"; };
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
@ -2632,6 +2634,7 @@
isa = PBXGroup;
children = (
B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */,
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */,
B8162F0222891AD600D46544 /* FriendRequestView.swift */,
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */,
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */,
@ -2642,7 +2645,7 @@
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */,
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */,
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */,
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */,
B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */,
);
path = Loki;
sourceTree = "<group>";
@ -3800,6 +3803,7 @@
34ABC0E421DD20C500ED9469 /* ConversationMessageMapping.swift in Sources */,
B821F2F82272CED3002C88C0 /* AccountDetailsViewController.swift in Sources */,
34D8C0271ED3673300188D7C /* DebugUIMessages.m in Sources */,
B885D5F62334A32100EE0D8E /* UIView+Constraint.swift in Sources */,
34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */,
34D1F0B41F86D31D0066283D /* ConversationCollectionView.m in Sources */,
34B3F8821E8DF1700035BE1A /* NewContactThreadViewController.m in Sources */,

View File

@ -60,49 +60,34 @@ final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDeleg
view.backgroundColor = .clear
// Content view
view.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32),
view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 32),
contentView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32).isActive = true
view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 32).isActive = true
contentView.center(.vertical, in: view)
// Spinner
contentView.addSubview(spinner)
spinner.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
spinner.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
spinner.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 32),
spinner.heightAnchor.constraint(equalToConstant: 64),
spinner.widthAnchor.constraint(equalToConstant: 64)
])
spinner.center(.horizontal, in: contentView)
spinner.pin(.top, to: .top, of: contentView, withInset: 32)
spinner.set(.width, to: 64)
spinner.set(.height, to: 64)
spinner.startAnimating()
// Title label
contentView.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
titleLabel.topAnchor.constraint(equalTo: spinner.bottomAnchor, constant: 32),
contentView.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 16)
])
titleLabel.pin(.leading, to: .leading, of: contentView, withInset: 16)
titleLabel.pin(.top, to: .bottom, of: spinner, withInset: 32)
contentView.pin(.trailing, to: .trailing, of: titleLabel, withInset: 16)
// Subtitle label
contentView.addSubview(subtitleLabel)
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
subtitleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),
contentView.trailingAnchor.constraint(equalTo: subtitleLabel.trailingAnchor, constant: 16)
])
subtitleLabel.pin(.leading, to: .leading, of: contentView, withInset: 16)
subtitleLabel.pin(.top, to: .bottom, of: titleLabel, withInset: 32)
contentView.pin(.trailing, to: .trailing, of: subtitleLabel, withInset: 16)
// Cancel button
contentView.addSubview(cancelButton)
cancelButton.translatesAutoresizingMaskIntoConstraints = false
cancelButton.pin(.leading, to: .leading, of: contentView, withInset: 16)
cancelButton.pin(.top, to: .bottom, of: subtitleLabel, withInset: 16)
contentView.pin(.trailing, to: .trailing, of: cancelButton, withInset: 16)
contentView.pin(.bottom, to: .bottom, of: cancelButton, withInset: 16)
let cancelButtonHeight = cancelButton.button.titleLabel!.font.pointSize * 48 / 17
NSLayoutConstraint.activate([
cancelButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
cancelButton.topAnchor.constraint(equalTo: subtitleLabel.bottomAnchor, constant: 16),
contentView.trailingAnchor.constraint(equalTo: cancelButton.trailingAnchor, constant: 16),
contentView.bottomAnchor.constraint(equalTo: cancelButton.bottomAnchor, constant: 16),
cancelButton.heightAnchor.constraint(equalToConstant: cancelButtonHeight)
])
cancelButton.set(.height, to: cancelButtonHeight)
}
// MARK: Device Linking
@ -121,11 +106,12 @@ final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDeleg
if contentView.frame.contains(location) {
super.touchesBegan(touches, with: event)
} else {
dismiss(animated: true, completion: nil)
cancel()
}
}
@objc private func cancel() {
deviceLinkingSession.stopListeningForLinkingRequests()
dismiss(animated: true, completion: nil)
}
}

View File

@ -0,0 +1,50 @@
extension UIView {
enum HorizontalEdge { case left, leading, right, trailing }
enum VerticalEdge { case top, bottom }
enum Direction { case horizontal, vertical }
enum Dimension { case width, height }
private func anchor(from edge: HorizontalEdge) -> NSLayoutXAxisAnchor {
switch edge {
case .left: return leftAnchor
case .leading: return leadingAnchor
case .right: return rightAnchor
case .trailing: return trailingAnchor
}
}
private func anchor(from edge: VerticalEdge) -> NSLayoutYAxisAnchor {
switch edge {
case .top: return topAnchor
case .bottom: return bottomAnchor
}
}
func pin(_ constraineeEdge: HorizontalEdge, to constrainerEdge: HorizontalEdge, of view: UIView, withInset inset: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
anchor(from: constraineeEdge).constraint(equalTo: view.anchor(from: constrainerEdge), constant: inset).isActive = true
}
func pin(_ constraineeEdge: VerticalEdge, to constrainerEdge: VerticalEdge, of view: UIView, withInset inset: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
anchor(from: constraineeEdge).constraint(equalTo: view.anchor(from: constrainerEdge), constant: inset).isActive = true
}
func center(_ direction: Direction, in view: UIView) {
translatesAutoresizingMaskIntoConstraints = false
switch direction {
case .horizontal: centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
case .vertical: centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
func set(_ dimension: Dimension, to size: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
switch dimension {
case .width: widthAnchor.constraint(equalToConstant: size).isActive = true
case .height: heightAnchor.constraint(equalToConstant: size).isActive = true
}
}
}