From 5ea1c5aea8906e2bb330630d0102ee2154b5869f Mon Sep 17 00:00:00 2001 From: Roopesh Chander Date: Tue, 6 Nov 2018 16:48:53 +0530 Subject: [PATCH] Tunnel detail: Refactor out the label scrolling into a separate UI class --- WireGuard/WireGuard.xcodeproj/project.pbxproj | 4 ++ .../WireGuard/UI/iOS/ScrollableLabel.swift | 50 +++++++++++++++++++ .../iOS/TunnelDetailTableViewController.swift | 40 ++++----------- 3 files changed, 63 insertions(+), 31 deletions(-) create mode 100644 WireGuard/WireGuard/UI/iOS/ScrollableLabel.swift diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj index 9ff9e77..b946736 100644 --- a/WireGuard/WireGuard.xcodeproj/project.pbxproj +++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */; }; + 6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0068562191AFD200419BE9 /* ScrollableLabel.swift */; }; 6F5D0C1521832391000F85AD /* DNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C1421832391000F85AD /* DNSResolver.swift */; }; 6F5D0C1D218352EF000F85AD /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C1C218352EF000F85AD /* PacketTunnelProvider.swift */; }; 6F5D0C22218352EF000F85AD /* WireGuardNetworkExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6F5D0C1A218352EF000F85AD /* WireGuardNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -78,6 +79,7 @@ /* Begin PBXFileReference section */ 6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CopyableLabelTableViewCell.swift; sourceTree = ""; }; + 6F0068562191AFD200419BE9 /* ScrollableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollableLabel.swift; sourceTree = ""; }; 6F5D0C1421832391000F85AD /* DNSResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSResolver.swift; sourceTree = ""; }; 6F5D0C1A218352EF000F85AD /* WireGuardNetworkExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WireGuardNetworkExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 6F5D0C1C218352EF000F85AD /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = ""; }; @@ -205,6 +207,7 @@ 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */, 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */, 6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */, + 6F0068562191AFD200419BE9 /* ScrollableLabel.swift */, ); path = iOS; sourceTree = ""; @@ -500,6 +503,7 @@ 6F5D0C482183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift in Sources */, 6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */, 6F693A562179E556008551C1 /* Endpoint.swift in Sources */, + 6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */, 6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */, 6F6899A62180447E0012E523 /* x25519.c in Sources */, 6F5D0C452183BCDA000F85AD /* PacketTunnelOptionKey.swift in Sources */, diff --git a/WireGuard/WireGuard/UI/iOS/ScrollableLabel.swift b/WireGuard/WireGuard/UI/iOS/ScrollableLabel.swift new file mode 100644 index 0000000..780d6c8 --- /dev/null +++ b/WireGuard/WireGuard/UI/iOS/ScrollableLabel.swift @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018 WireGuard LLC. All Rights Reserved. + +import UIKit + +class ScrollableLabel: UIScrollView { + var text: String { + get { return label.text ?? "" } + set(value) { label.text = value } + } + var textColor: UIColor { + get { return label.textColor } + set(value) { label.textColor = value } + } + + private let label: UILabel + + init() { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.textAlignment = .right + self.label = label + + super.init(frame: CGRect.zero) + + self.isDirectionalLockEnabled = true + self.showsHorizontalScrollIndicator = false + self.showsVerticalScrollIndicator = false + + addSubview(label) + label.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + label.leftAnchor.constraint(equalTo: self.contentLayoutGuide.leftAnchor), + label.topAnchor.constraint(equalTo: self.contentLayoutGuide.topAnchor), + label.bottomAnchor.constraint(equalTo: self.contentLayoutGuide.bottomAnchor), + label.rightAnchor.constraint(equalTo: self.contentLayoutGuide.rightAnchor), + label.heightAnchor.constraint(equalTo: self.heightAnchor), + ]) + // If label has less content, it should expand to fit the scrollView, + // so that right-alignment works in the label. + let expandToFitValueLabelConstraint = NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal, + toItem: self, attribute: .width, multiplier: 1, constant: 0) + expandToFitValueLabelConstraint.priority = .defaultLow + 1 + expandToFitValueLabelConstraint.isActive = true + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift b/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift index 64aaa7b..9120f38 100644 --- a/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift +++ b/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift @@ -296,7 +296,7 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell { set(value) { keyLabel.text = value } } var value: String { - get { return valueLabel.text ?? "" } + get { return valueLabel.text } set(value) { valueLabel.text = value } } @@ -305,39 +305,17 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell { } let keyLabel: UILabel - let valueLabel: UILabel - let valueScroller: UIScrollView + let valueLabel: ScrollableLabel override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { keyLabel = UILabel() - valueLabel = UILabel() - valueScroller = UIScrollView() + valueLabel = ScrollableLabel() keyLabel.textColor = UIColor.black valueLabel.textColor = UIColor.gray - valueScroller.isDirectionalLockEnabled = true - valueScroller.showsHorizontalScrollIndicator = false - valueScroller.showsVerticalScrollIndicator = false super.init(style: style, reuseIdentifier: reuseIdentifier) - valueScroller.addSubview(valueLabel) - valueLabel.translatesAutoresizingMaskIntoConstraints = false - valueLabel.textAlignment = .right - NSLayoutConstraint.activate([ - valueLabel.leftAnchor.constraint(equalTo: valueScroller.contentLayoutGuide.leftAnchor), - valueLabel.topAnchor.constraint(equalTo: valueScroller.contentLayoutGuide.topAnchor), - valueLabel.bottomAnchor.constraint(equalTo: valueScroller.contentLayoutGuide.bottomAnchor), - valueLabel.rightAnchor.constraint(equalTo: valueScroller.contentLayoutGuide.rightAnchor), - valueLabel.heightAnchor.constraint(equalTo: valueScroller.heightAnchor), - ]) - - // Value label should expand to fit the scrollView, so that the right-alignment works - let expandToFitValueLabelConstraint = NSLayoutConstraint(item: valueLabel, attribute: .width, relatedBy: .equal, - toItem: valueScroller, attribute: .width, multiplier: 1, constant: 0) - expandToFitValueLabelConstraint.priority = .defaultLow + 1 - expandToFitValueLabelConstraint.isActive = true - contentView.addSubview(keyLabel) keyLabel.translatesAutoresizingMaskIntoConstraints = false keyLabel.textAlignment = .left @@ -346,19 +324,19 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell { keyLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor) ]) - contentView.addSubview(valueScroller) - valueScroller.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(valueLabel) + valueLabel.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - valueScroller.rightAnchor.constraint(equalTo: contentView.layoutMarginsGuide.rightAnchor), - valueScroller.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - valueScroller.leftAnchor.constraint(equalTo: keyLabel.rightAnchor, constant: 8) + valueLabel.rightAnchor.constraint(equalTo: contentView.layoutMarginsGuide.rightAnchor), + valueLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + valueLabel.leftAnchor.constraint(equalTo: keyLabel.rightAnchor, constant: 8) ]) // Key label should never appear truncated keyLabel.setContentCompressionResistancePriority(.defaultHigh + 1, for: .horizontal) // Key label should hug it's content; value label should not. keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal) - valueScroller.setContentHuggingPriority(.defaultLow, for: .horizontal) + valueLabel.setContentHuggingPriority(.defaultLow, for: .horizontal) } required init?(coder aDecoder: NSCoder) {