Tunnel detail: Refactor out the label scrolling into a separate UI class
This commit is contained in:
parent
e9044966bf
commit
5ea1c5aea8
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */; };
|
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 */; };
|
6F5D0C1521832391000F85AD /* DNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C1421832391000F85AD /* DNSResolver.swift */; };
|
||||||
6F5D0C1D218352EF000F85AD /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C1C218352EF000F85AD /* PacketTunnelProvider.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, ); }; };
|
6F5D0C22218352EF000F85AD /* WireGuardNetworkExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6F5D0C1A218352EF000F85AD /* WireGuardNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
@ -78,6 +79,7 @@
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CopyableLabelTableViewCell.swift; sourceTree = "<group>"; };
|
6BB8400321892C920003598F /* CopyableLabelTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CopyableLabelTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
6F0068562191AFD200419BE9 /* ScrollableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollableLabel.swift; sourceTree = "<group>"; };
|
||||||
6F5D0C1421832391000F85AD /* DNSResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSResolver.swift; sourceTree = "<group>"; };
|
6F5D0C1421832391000F85AD /* DNSResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSResolver.swift; sourceTree = "<group>"; };
|
||||||
6F5D0C1A218352EF000F85AD /* WireGuardNetworkExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WireGuardNetworkExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
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 = "<group>"; };
|
6F5D0C1C218352EF000F85AD /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
|
||||||
|
@ -205,6 +207,7 @@
|
||||||
6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */,
|
6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */,
|
||||||
6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */,
|
6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */,
|
||||||
6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */,
|
6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */,
|
||||||
|
6F0068562191AFD200419BE9 /* ScrollableLabel.swift */,
|
||||||
);
|
);
|
||||||
path = iOS;
|
path = iOS;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -500,6 +503,7 @@
|
||||||
6F5D0C482183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift in Sources */,
|
6F5D0C482183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift in Sources */,
|
||||||
6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */,
|
6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */,
|
||||||
6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
|
6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
|
||||||
|
6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */,
|
||||||
6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,
|
6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,
|
||||||
6F6899A62180447E0012E523 /* x25519.c in Sources */,
|
6F6899A62180447E0012E523 /* x25519.c in Sources */,
|
||||||
6F5D0C452183BCDA000F85AD /* PacketTunnelOptionKey.swift in Sources */,
|
6F5D0C452183BCDA000F85AD /* PacketTunnelOptionKey.swift in Sources */,
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
|
@ -296,7 +296,7 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
|
||||||
set(value) { keyLabel.text = value }
|
set(value) { keyLabel.text = value }
|
||||||
}
|
}
|
||||||
var value: String {
|
var value: String {
|
||||||
get { return valueLabel.text ?? "" }
|
get { return valueLabel.text }
|
||||||
set(value) { valueLabel.text = value }
|
set(value) { valueLabel.text = value }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,39 +305,17 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
let keyLabel: UILabel
|
let keyLabel: UILabel
|
||||||
let valueLabel: UILabel
|
let valueLabel: ScrollableLabel
|
||||||
let valueScroller: UIScrollView
|
|
||||||
|
|
||||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
keyLabel = UILabel()
|
keyLabel = UILabel()
|
||||||
valueLabel = UILabel()
|
valueLabel = ScrollableLabel()
|
||||||
valueScroller = UIScrollView()
|
|
||||||
|
|
||||||
keyLabel.textColor = UIColor.black
|
keyLabel.textColor = UIColor.black
|
||||||
valueLabel.textColor = UIColor.gray
|
valueLabel.textColor = UIColor.gray
|
||||||
valueScroller.isDirectionalLockEnabled = true
|
|
||||||
valueScroller.showsHorizontalScrollIndicator = false
|
|
||||||
valueScroller.showsVerticalScrollIndicator = false
|
|
||||||
|
|
||||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
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)
|
contentView.addSubview(keyLabel)
|
||||||
keyLabel.translatesAutoresizingMaskIntoConstraints = false
|
keyLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
keyLabel.textAlignment = .left
|
keyLabel.textAlignment = .left
|
||||||
|
@ -346,19 +324,19 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
|
||||||
keyLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
|
keyLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
|
||||||
])
|
])
|
||||||
|
|
||||||
contentView.addSubview(valueScroller)
|
contentView.addSubview(valueLabel)
|
||||||
valueScroller.translatesAutoresizingMaskIntoConstraints = false
|
valueLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
valueScroller.rightAnchor.constraint(equalTo: contentView.layoutMarginsGuide.rightAnchor),
|
valueLabel.rightAnchor.constraint(equalTo: contentView.layoutMarginsGuide.rightAnchor),
|
||||||
valueScroller.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
valueLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||||
valueScroller.leftAnchor.constraint(equalTo: keyLabel.rightAnchor, constant: 8)
|
valueLabel.leftAnchor.constraint(equalTo: keyLabel.rightAnchor, constant: 8)
|
||||||
])
|
])
|
||||||
|
|
||||||
// Key label should never appear truncated
|
// Key label should never appear truncated
|
||||||
keyLabel.setContentCompressionResistancePriority(.defaultHigh + 1, for: .horizontal)
|
keyLabel.setContentCompressionResistancePriority(.defaultHigh + 1, for: .horizontal)
|
||||||
// Key label should hug it's content; value label should not.
|
// Key label should hug it's content; value label should not.
|
||||||
keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||||
valueScroller.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
valueLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
|
Loading…
Reference in New Issue