Update design of 'approve contact share' view.

This commit is contained in:
Matthew Chen 2018-05-04 17:13:42 -04:00
parent b0c4ad7f63
commit 50c49baca8
8 changed files with 243 additions and 301 deletions

View File

@ -164,6 +164,8 @@
347850711FDAEB17007B8332 /* OWSUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 3478506F1FDAEB16007B8332 /* OWSUserProfile.m */; };
347850721FDAEB17007B8332 /* OWSUserProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 347850701FDAEB16007B8332 /* OWSUserProfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
348BB254209CD4B80047AEC2 /* ContactFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348BB253209CD4B80047AEC2 /* ContactFieldView.swift */; };
348BB25A209CF8E50047AEC2 /* TappableStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348BB258209CF8E40047AEC2 /* TappableStackView.swift */; };
348BB25B209CF8E50047AEC2 /* TappableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348BB259209CF8E50047AEC2 /* TappableView.swift */; };
3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3496744C2076768700080B5F /* OWSMessageBubbleView.m */; };
3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3496744E2076ACCE00080B5F /* LongTextViewController.swift */; };
34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34A55F3520485464002CC6DE /* OWS2FARegistrationViewController.m */; };
@ -762,6 +764,8 @@
3478506F1FDAEB16007B8332 /* OWSUserProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSUserProfile.m; sourceTree = "<group>"; };
347850701FDAEB16007B8332 /* OWSUserProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSUserProfile.h; sourceTree = "<group>"; };
348BB253209CD4B80047AEC2 /* ContactFieldView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContactFieldView.swift; path = SignalMessaging/attachments/ContactFieldView.swift; sourceTree = SOURCE_ROOT; };
348BB258209CF8E40047AEC2 /* TappableStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TappableStackView.swift; path = SignalMessaging/Views/TappableStackView.swift; sourceTree = SOURCE_ROOT; };
348BB259209CF8E50047AEC2 /* TappableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TappableView.swift; path = SignalMessaging/Views/TappableView.swift; sourceTree = SOURCE_ROOT; };
348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceSleepManager.swift; sourceTree = "<group>"; };
3495BC911F1426B800B478F5 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = translations/ar.lproj/Localizable.strings; sourceTree = "<group>"; };
3496744B2076768600080B5F /* OWSMessageBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageBubbleView.h; sourceTree = "<group>"; };
@ -1586,15 +1590,17 @@
isa = PBXGroup;
children = (
45F3AEB51DFDE7900080CE33 /* AvatarImageView.swift */,
76EB052E18170B33006006FC /* ContactTableViewCell.h */,
76EB052F18170B33006006FC /* ContactTableViewCell.m */,
346129D11FD2085A00532771 /* CommonStrings.swift */,
340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */,
340CB2231EAC155C0001CAA1 /* ContactsViewHelper.m */,
346129D11FD2085A00532771 /* CommonStrings.swift */,
76EB052E18170B33006006FC /* ContactTableViewCell.h */,
76EB052F18170B33006006FC /* ContactTableViewCell.m */,
45BE4EA12012AD2000935E59 /* DisappearingTimerConfigurationView.swift */,
451573952061B49500803601 /* GradientView.swift */,
346129CF1FD207F200532771 /* OWSAlerts.swift */,
454A965E1FD60EA2008D2A0E /* OWSFlatButton.swift */,
348BB258209CF8E40047AEC2 /* TappableStackView.swift */,
348BB259209CF8E50047AEC2 /* TappableView.swift */,
3400C7971EAFB772008A8584 /* ThreadViewHelper.h */,
3400C7981EAFB772008A8584 /* ThreadViewHelper.m */,
);
@ -3083,6 +3089,8 @@
451F8A461FD715BA005CB9DA /* OWSGroupAvatarBuilder.m in Sources */,
347850591FD9972E007B8332 /* SwiftSingletons.swift in Sources */,
344F248720069ECB00CFB4F4 /* ModalActivityIndicatorViewController.swift in Sources */,
348BB25B209CF8E50047AEC2 /* TappableView.swift in Sources */,
348BB25A209CF8E50047AEC2 /* TappableStackView.swift in Sources */,
346129961FD1E30000532771 /* OWSDatabaseMigration.m in Sources */,
344D6CEC20069E070042AF96 /* NewNonContactConversationViewController.m in Sources */,
346129FB1FD5F31400532771 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */,

View File

@ -9,36 +9,6 @@ import Reachability
import ContactsUI
import MessageUI
class TappableView: UIView {
let actionBlock : (() -> Void)
// MARK: - Initializers
@available(*, unavailable, message: "use other constructor instead.")
required init?(coder aDecoder: NSCoder) {
fatalError("Unimplemented")
}
required init(actionBlock : @escaping () -> Void) {
self.actionBlock = actionBlock
super.init(frame: CGRect.zero)
self.isUserInteractionEnabled = true
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(wasTapped)))
}
func wasTapped(sender: UIGestureRecognizer) {
Logger.info("\(logTag) \(#function)")
guard sender.state == .recognized else {
return
}
actionBlock()
}
}
// MARK: -
class ContactViewController: OWSViewController, CNContactViewControllerDelegate {
enum ContactViewMode {
@ -372,37 +342,35 @@ class ContactViewController: OWSViewController, CNContactViewControllerDelegate
// }
for phoneNumber in contactShare.phoneNumbers {
let formattedPhoneNumber = PhoneNumber.bestEffortLocalizedPhoneNumber(withE164: phoneNumber.phoneNumber)
rows.append(createSimpleFieldRow(name: phoneNumber.localizedLabel(),
value: formattedPhoneNumber,
actionBlock: {
guard let url = NSURL(string: "tel:\(phoneNumber.phoneNumber)") else {
owsFail("\(ContactViewController.logTag) could not open phone number.")
return
}
UIApplication.shared.openURL(url as URL)
rows.append(ContactFieldView.contactFieldView(forPhoneNumber: phoneNumber,
layoutMargins: UIEdgeInsets(top: 5, left: hMargin, bottom: 5, right: hMargin),
actionBlock: {
guard let url = NSURL(string: "tel:\(phoneNumber.phoneNumber)") else {
owsFail("\(ContactViewController.logTag) could not open phone number.")
return
}
UIApplication.shared.openURL(url as URL)
}))
}
for email in contactShare.emails {
rows.append(createSimpleFieldRow(name: email.localizedLabel(),
value: email.email,
actionBlock: {
guard let url = NSURL(string: "mailto:\(email.email)") else {
owsFail("\(ContactViewController.logTag) could not open email.")
return
}
UIApplication.shared.openURL(url as URL)
rows.append(ContactFieldView.contactFieldView(forEmail: email,
layoutMargins: UIEdgeInsets(top: 5, left: hMargin, bottom: 5, right: hMargin),
actionBlock: {
guard let url = NSURL(string: "mailto:\(email.email)") else {
owsFail("\(ContactViewController.logTag) could not open email.")
return
}
UIApplication.shared.openURL(url as URL)
}))
}
for address in contactShare.addresses {
rows.append(createAddressFieldRow(name: address.localizedLabel(),
address: address,
actionBlock: { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.didPressAddress(address: address)
rows.append(ContactFieldView.contactFieldView(forAddress: address,
layoutMargins: UIEdgeInsets(top: 5, left: hMargin, bottom: 5, right: hMargin),
actionBlock: { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.didPressAddress(address: address)
}))
}
@ -432,112 +400,6 @@ class ContactViewController: OWSViewController, CNContactViewControllerDelegate
return row
}
private func createSimpleFieldRow(name: String, value: String?, actionBlock : @escaping () -> Void) -> UIView {
let row = TappableView(actionBlock: actionBlock)
row.layoutMargins.left = 0
row.layoutMargins.right = 0
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .leading
stackView.spacing = 3
row.addSubview(stackView)
stackView.autoPinTopToSuperviewMargin()
stackView.autoPinBottomToSuperviewMargin()
stackView.autoPinLeadingToSuperviewMargin(withInset: hMargin)
stackView.autoPinTrailingToSuperviewMargin(withInset: hMargin)
let nameLabel = UILabel()
nameLabel.text = name
nameLabel.font = UIFont.ows_dynamicTypeSubheadline
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
stackView.addArrangedSubview(nameLabel)
let valueLabel = UILabel()
valueLabel.text = value
valueLabel.font = UIFont.ows_dynamicTypeBody
valueLabel.textColor = UIColor.ows_materialBlue
valueLabel.lineBreakMode = .byTruncatingTail
stackView.addArrangedSubview(valueLabel)
return row
}
private func createAddressFieldRow(name: String, address: OWSContactAddress, actionBlock : @escaping () -> Void) -> UIView {
let row = TappableView(actionBlock: actionBlock)
row.layoutMargins.left = 0
row.layoutMargins.right = 0
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .leading
stackView.spacing = 3
stackView.layoutMargins = .zero
row.addSubview(stackView)
stackView.autoPinTopToSuperviewMargin()
stackView.autoPinBottomToSuperviewMargin()
stackView.autoPinLeadingToSuperviewMargin(withInset: hMargin)
stackView.autoPinTrailingToSuperviewMargin(withInset: hMargin)
let nameLabel = UILabel()
nameLabel.text = name
nameLabel.font = UIFont.ows_dynamicTypeSubheadline
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
stackView.addArrangedSubview(nameLabel)
let tryToAddNameValue: ((String, String?) -> Void) = { (propertyName, propertyValue) in
guard let propertyValue = propertyValue else {
return
}
guard propertyValue.count > 0 else {
return
}
let row = UIStackView()
row.axis = .horizontal
row.alignment = .leading
row.spacing = 10
row.layoutMargins = .zero
let nameLabel = UILabel()
nameLabel.text = propertyName
nameLabel.font = UIFont.ows_dynamicTypeBody
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
row.addArrangedSubview(nameLabel)
nameLabel.setContentHuggingHigh()
nameLabel.setCompressionResistanceHigh()
let valueLabel = UILabel()
valueLabel.text = propertyValue
valueLabel.font = UIFont.ows_dynamicTypeBody
valueLabel.textColor = UIColor.ows_materialBlue
valueLabel.lineBreakMode = .byTruncatingTail
row.addArrangedSubview(valueLabel)
stackView.addArrangedSubview(row)
}
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_STREET", comment: "Label for the 'street' field of a contact's address."),
address.street)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POBOX", comment: "Label for the 'pobox' field of a contact's address."),
address.pobox)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_NEIGHBORHOOD", comment: "Label for the 'neighborhood' field of a contact's address."),
address.neighborhood)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_CITY", comment: "Label for the 'city' field of a contact's address."),
address.city)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_REGION", comment: "Label for the 'region' field of a contact's address."),
address.region)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POSTCODE", comment: "Label for the 'postcode' field of a contact's address."),
address.postcode)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_COUNTRY", comment: "Label for the 'country' field of a contact's address."),
address.country)
return row
}
// TODO: Use real assets.
private func createCircleActionButton(text: String, actionBlock : @escaping () -> Void) -> UIView {
let buttonSize = CGFloat(50)

View File

@ -244,6 +244,8 @@ public class ContactsPicker: OWSViewController, UITableViewDelegate, UITableView
}
open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
Logger.verbose("\(logTag) \(#function)")
let cell = tableView.cellForRow(at: indexPath) as! ContactCell
let selectedContact = cell.contact!

View File

@ -0,0 +1,33 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
public class TappableStackView: UIStackView {
let actionBlock : (() -> Void)
// MARK: - Initializers
@available(*, unavailable, message: "use other constructor instead.")
public required init(coder aDecoder: NSCoder) {
fatalError("Unimplemented")
}
public required init(actionBlock : @escaping () -> Void) {
self.actionBlock = actionBlock
super.init(frame: CGRect.zero)
self.isUserInteractionEnabled = true
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(wasTapped)))
}
func wasTapped(sender: UIGestureRecognizer) {
Logger.info("\(logTag) \(#function)")
guard sender.state == .recognized else {
return
}
actionBlock()
}
}

View File

@ -0,0 +1,33 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
public class TappableView: UIView {
let actionBlock : (() -> Void)
// MARK: - Initializers
@available(*, unavailable, message: "use other constructor instead.")
public required init?(coder aDecoder: NSCoder) {
fatalError("Unimplemented")
}
public required init(actionBlock : @escaping () -> Void) {
self.actionBlock = actionBlock
super.init(frame: CGRect.zero)
self.isUserInteractionEnabled = true
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(wasTapped)))
}
func wasTapped(sender: UIGestureRecognizer) {
Logger.info("\(logTag) \(#function)")
guard sender.state == .recognized else {
return
}
actionBlock()
}
}

View File

@ -97,7 +97,7 @@ class ContactShareAddress: ContactShareFieldBase<OWSContactAddress> {
// MARK: -
class ContactShareFieldView: UIView {
class ContactShareFieldView: UIStackView {
let field: ContactShareField
@ -108,7 +108,7 @@ class ContactShareFieldView: UIView {
// MARK: - Initializers
@available(*, unavailable, message: "use init(call:) constructor instead.")
required init?(coder aDecoder: NSCoder) {
required init(coder aDecoder: NSCoder) {
fatalError("Unimplemented")
}
@ -125,11 +125,14 @@ class ContactShareFieldView: UIView {
}
let hSpacing = CGFloat(10)
let hMargin = CGFloat(0)
let hMargin = CGFloat(16)
func createContents() {
self.layoutMargins.left = 0
self.layoutMargins.right = 0
self.axis = .horizontal
self.spacing = hSpacing
self.alignment = .center
self.layoutMargins = UIEdgeInsets(top: 0, left: hMargin, bottom: 0, right: hMargin)
self.isLayoutMarginsRelativeArrangement = true
let checkbox = UIButton(type: .custom)
self.checkbox = checkbox
@ -142,28 +145,12 @@ class ContactShareFieldView: UIView {
checkbox.isSelected = field.isIncluded()
// Disable the checkbox; the entire row is hot.
checkbox.isUserInteractionEnabled = false
addSubview(checkbox)
checkbox.autoPinEdge(toSuperviewEdge: .leading, withInset: hMargin)
checkbox.autoVCenterInSuperview()
self.addArrangedSubview(checkbox)
checkbox.setCompressionResistanceHigh()
checkbox.setContentHuggingHigh()
let nameLabel = UILabel()
nameLabel.text = field.localizedLabel()
nameLabel.font = UIFont.ows_dynamicTypeCaption1
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
addSubview(nameLabel)
nameLabel.autoPinTopToSuperviewMargin()
nameLabel.autoPinLeading(toTrailingEdgeOf: checkbox, offset: hSpacing)
nameLabel.autoPinTrailingToSuperviewMargin(withInset: hMargin)
let previewView = previewViewBlock()
addSubview(previewView)
previewView.autoPinEdge(.top, to: .bottom, of: nameLabel, withOffset: 3)
previewView.autoPinBottomToSuperviewMargin()
previewView.autoPinLeading(toTrailingEdgeOf: checkbox, offset: hSpacing)
previewView.autoPinTrailingToSuperviewMargin(withInset: hMargin)
self.addArrangedSubview(previewView)
}
func wasTapped(sender: UIGestureRecognizer) {
@ -215,27 +202,26 @@ public class ApproveContactShareViewController: OWSViewController, EditContactSh
// TODO: Avatar
let previewInsets = UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 0)
for phoneNumber in contactShare.phoneNumbers {
let field = ContactSharePhoneNumber(phoneNumber)
let fieldView = ContactShareFieldView(field: field, previewViewBlock: { [weak self] _ in
guard let strongSelf = self else { return UIView() }
return strongSelf.previewView(forPhoneNumber: phoneNumber)
let fieldView = ContactShareFieldView(field: field, previewViewBlock: {
return ContactFieldView.contactFieldView(forPhoneNumber: phoneNumber, layoutMargins: previewInsets, actionBlock: nil)
})
fieldViews.append(fieldView)
}
for email in contactShare.emails {
let field = ContactShareEmail(email)
let fieldView = ContactShareFieldView(field: field, previewViewBlock: { [weak self] _ in
guard let strongSelf = self else { return UIView() }
return strongSelf.previewView(forEmail: email)
let fieldView = ContactShareFieldView(field: field, previewViewBlock: {
return ContactFieldView.contactFieldView(forEmail: email, layoutMargins: previewInsets, actionBlock: nil)
})
fieldViews.append(fieldView)
}
for address in contactShare.addresses {
let field = ContactShareAddress(address)
let fieldView = ContactShareFieldView(field: field, previewViewBlock: { [weak self] _ in
guard let strongSelf = self else { return UIView() }
return strongSelf.previewView(forAddress: address)
let fieldView = ContactShareFieldView(field: field, previewViewBlock: {
return ContactFieldView.contactFieldView(forAddress: address, layoutMargins: previewInsets, actionBlock: nil)
})
fieldViews.append(fieldView)
}
@ -347,126 +333,33 @@ public class ApproveContactShareViewController: OWSViewController, EditContactSh
func createNameRow() -> UIView {
let nameVMargin = CGFloat(16)
let row = UIView()
row.layoutMargins = UIEdgeInsets(top: nameVMargin, left: 0, bottom: nameVMargin, right: 0)
let stackView = TappableStackView(actionBlock: { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.didPressEditName()
})
let stackView = UIStackView()
stackView.axis = .horizontal
stackView.alignment = .center
stackView.layoutMargins = .zero
stackView.layoutMargins = UIEdgeInsets(top: nameVMargin, left: hMargin, bottom: nameVMargin, right: hMargin)
stackView.spacing = 10
row.addSubview(stackView)
stackView.autoPinEdgesToSuperviewMargins()
stackView.isLayoutMarginsRelativeArrangement = true
let nameLabel = UILabel()
self.nameLabel = nameLabel
nameLabel.text = contactShare.displayName
nameLabel.font = UIFont.ows_dynamicTypeBody
nameLabel.textColor = UIColor.ows_materialBlue
nameLabel.font = UIFont.ows_dynamicTypeBody.ows_mediumWeight()
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
stackView.addArrangedSubview(nameLabel)
let editNameLabel = UILabel()
editNameLabel.text = NSLocalizedString("CONTACT_EDIT_NAME_BUTTON", comment: "Label for the 'edit name' button in the contact share approval view.")
editNameLabel.font = UIFont.ows_dynamicTypeCaption1
editNameLabel.textColor = UIColor.black
editNameLabel.font = UIFont.ows_dynamicTypeBody
editNameLabel.textColor = UIColor.ows_materialBlue
stackView.addArrangedSubview(editNameLabel)
editNameLabel.setContentHuggingHigh()
editNameLabel.setCompressionResistanceHigh()
// Icon
let iconName = (self.view.isRTL() ? "system_disclosure_indicator_rtl" : "system_disclosure_indicator")
guard let iconImage = UIImage(named: iconName) else {
owsFail("\(logTag) missing icon.")
return row
}
let iconView = UIImageView(image: iconImage.withRenderingMode(.alwaysTemplate))
iconView.contentMode = .scaleAspectFit
iconView.tintColor = UIColor.black.withAlphaComponent(0.6)
stackView.addArrangedSubview(iconView)
iconView.setContentHuggingHigh()
iconView.setCompressionResistanceHigh()
row.isUserInteractionEnabled = true
row.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didPressEditName)))
return row
}
func previewView(forPhoneNumber phoneNumber: OWSContactPhoneNumber) -> UIView {
let label = UILabel()
label.text = PhoneNumber.bestEffortLocalizedPhoneNumber(withE164: phoneNumber.phoneNumber)
label.font = UIFont.ows_dynamicTypeCaption1
label.textColor = UIColor.ows_materialBlue
label.lineBreakMode = .byTruncatingTail
return label
}
func previewView(forEmail email: OWSContactEmail) -> UIView {
let label = UILabel()
label.text = email.email
label.font = UIFont.ows_dynamicTypeCaption1
label.textColor = UIColor.ows_materialBlue
label.lineBreakMode = .byTruncatingTail
return label
}
func previewView(forAddress address: OWSContactAddress) -> UIView {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .leading
stackView.spacing = 0
stackView.layoutMargins = .zero
let tryToAddNameValue: ((String, String?) -> Void) = { (name, value) in
guard let value = value else {
return
}
guard value.count > 0 else {
return
}
let row = UIView.container()
let nameLabel = UILabel()
nameLabel.text = name
nameLabel.font = UIFont.ows_dynamicTypeCaption1
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
row.addSubview(nameLabel)
nameLabel.autoPinLeadingToSuperviewMargin()
nameLabel.autoPinHeightToSuperview()
nameLabel.setContentHuggingHigh()
nameLabel.setCompressionResistanceHigh()
let valueLabel = UILabel()
valueLabel.text = value
valueLabel.font = UIFont.ows_dynamicTypeCaption1
valueLabel.textColor = UIColor.ows_materialBlue
valueLabel.lineBreakMode = .byTruncatingTail
row.addSubview(valueLabel)
valueLabel.autoPinLeading(toTrailingEdgeOf: nameLabel, offset: 10)
valueLabel.autoPinTrailingToSuperviewMargin()
valueLabel.autoPinHeightToSuperview()
stackView.addArrangedSubview(row)
}
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_STREET", comment: "Label for the 'street' field of a contact's address."),
address.street)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POBOX", comment: "Label for the 'pobox' field of a contact's address."),
address.pobox)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_NEIGHBORHOOD", comment: "Label for the 'neighborhood' field of a contact's address."),
address.neighborhood)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_CITY", comment: "Label for the 'city' field of a contact's address."),
address.city)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_REGION", comment: "Label for the 'region' field of a contact's address."),
address.region)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POSTCODE", comment: "Label for the 'postcode' field of a contact's address."),
address.postcode)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_COUNTRY", comment: "Label for the 'country' field of a contact's address."),
address.country)
return stackView
}

View File

@ -44,8 +44,8 @@ public class ContactFieldView: UIView {
addSpacerRow()
}
self.addSubview(row)
row.autoPinLeadingToSuperviewMargin(withInset: hMargin)
row.autoPinTrailingToSuperviewMargin(withInset: hMargin)
row.autoPinLeadingToSuperviewMargin()
row.autoPinTrailingToSuperviewMargin()
if let lastRow = lastRow {
row.autoPinEdge(.top, to: .bottom, of: lastRow, withOffset: 0)
} else {
@ -60,4 +60,114 @@ public class ContactFieldView: UIView {
lastRow?.autoPinEdge(toSuperviewEdge: .bottom, withInset: 0)
}
public class func contactFieldView(forPhoneNumber phoneNumber: OWSContactPhoneNumber, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView {
let formattedPhoneNumber = PhoneNumber.bestEffortLocalizedPhoneNumber(withE164: phoneNumber.phoneNumber)
return simpleFieldView(name: phoneNumber.localizedLabel(), value: formattedPhoneNumber, layoutMargins: layoutMargins, actionBlock: actionBlock)
}
public class func contactFieldView(forEmail email: OWSContactEmail, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView {
return simpleFieldView(name: email.localizedLabel(), value: email.email, layoutMargins: layoutMargins, actionBlock: actionBlock)
}
private class func simpleFieldView(name: String, value: String?, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView {
var stackView: UIStackView
if let actionBlock = actionBlock {
stackView = TappableStackView(actionBlock: actionBlock)
} else {
stackView = UIStackView()
}
stackView.axis = .vertical
stackView.alignment = .leading
stackView.spacing = 3
stackView.layoutMargins = layoutMargins
stackView.isLayoutMarginsRelativeArrangement = true
let nameLabel = UILabel()
nameLabel.text = name
nameLabel.font = UIFont.ows_dynamicTypeSubheadline
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
stackView.addArrangedSubview(nameLabel)
let valueLabel = UILabel()
valueLabel.text = value
valueLabel.font = UIFont.ows_dynamicTypeBody
valueLabel.textColor = UIColor.ows_materialBlue
valueLabel.lineBreakMode = .byTruncatingTail
stackView.addArrangedSubview(valueLabel)
return stackView
}
public class func contactFieldView(forAddress address: OWSContactAddress, layoutMargins: UIEdgeInsets, actionBlock : (() -> Void)?) -> UIView {
var stackView: UIStackView
if let actionBlock = actionBlock {
stackView = TappableStackView(actionBlock: actionBlock)
} else {
stackView = UIStackView()
}
stackView.axis = .vertical
stackView.alignment = .leading
stackView.spacing = 3
stackView.layoutMargins = layoutMargins
stackView.isLayoutMarginsRelativeArrangement = true
let nameLabel = UILabel()
nameLabel.text = address.localizedLabel()
nameLabel.font = UIFont.ows_dynamicTypeSubheadline
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
stackView.addArrangedSubview(nameLabel)
let tryToAddNameValue: ((String, String?) -> Void) = { (propertyName, propertyValue) in
guard let propertyValue = propertyValue else {
return
}
guard propertyValue.count > 0 else {
return
}
let row = UIStackView()
row.axis = .horizontal
row.alignment = .leading
row.spacing = 10
row.layoutMargins = .zero
let nameLabel = UILabel()
nameLabel.text = propertyName
nameLabel.font = UIFont.ows_dynamicTypeBody
nameLabel.textColor = UIColor.black
nameLabel.lineBreakMode = .byTruncatingTail
row.addArrangedSubview(nameLabel)
nameLabel.setContentHuggingHigh()
nameLabel.setCompressionResistanceHigh()
let valueLabel = UILabel()
valueLabel.text = propertyValue
valueLabel.font = UIFont.ows_dynamicTypeBody
valueLabel.textColor = UIColor.ows_materialBlue
valueLabel.lineBreakMode = .byTruncatingTail
row.addArrangedSubview(valueLabel)
stackView.addArrangedSubview(row)
}
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_STREET", comment: "Label for the 'street' field of a contact's address."),
address.street)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POBOX", comment: "Label for the 'pobox' field of a contact's address."),
address.pobox)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_NEIGHBORHOOD", comment: "Label for the 'neighborhood' field of a contact's address."),
address.neighborhood)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_CITY", comment: "Label for the 'city' field of a contact's address."),
address.city)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_REGION", comment: "Label for the 'region' field of a contact's address."),
address.region)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_POSTCODE", comment: "Label for the 'postcode' field of a contact's address."),
address.postcode)
tryToAddNameValue(NSLocalizedString("CONTACT_FIELD_ADDRESS_COUNTRY", comment: "Label for the 'country' field of a contact's address."),
address.country)
return stackView
}
}

View File

@ -459,12 +459,13 @@ CGFloat ScaleFromIPhone5(CGFloat iPhone5Value)
- (void)logFrameWithLabel:(NSString *)label
{
DDLogVerbose(@"%@ %@ frame: %@, hidden: %d, opacity: %f",
DDLogVerbose(@"%@ %@ frame: %@, hidden: %d, opacity: %f, layoutMargins: %@",
self.logTag,
label,
NSStringFromCGRect(self.frame),
self.hidden,
self.layer.opacity);
self.layer.opacity,
NSStringFromUIEdgeInsets(self.layoutMargins));
}
- (void)logFrameLater