Add interaction to buttons that were missing it. Issue #1945

This commit is contained in:
Maurice Parker 2020-03-25 08:55:02 -05:00
parent 3c0862fe83
commit 6c06c7791c
4 changed files with 66 additions and 36 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/> <device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
<capability name="Named colors" minToolsVersion="9.0"/> <capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
@ -57,7 +57,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="o06-fe-i3S"> <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="o06-fe-i3S">
<rect key="frame" x="20" y="11.5" width="334" height="21"/> <rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" spellCheckingType="no" keyboardType="emailAddress" textContentType="username"/> <textInputTraits key="textInputTraits" spellCheckingType="no" keyboardType="emailAddress" textContentType="username"/>
</textField> </textField>
@ -206,7 +206,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Yl1-R6-xZi"> <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Yl1-R6-xZi">
<rect key="frame" x="20" y="11.5" width="334" height="21"/> <rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" autocapitalizationType="words"/> <textInputTraits key="textInputTraits" autocapitalizationType="words"/>
</textField> </textField>
@ -291,7 +291,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vJa-NN-yjR"> <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vJa-NN-yjR">
<rect key="frame" x="20" y="11.5" width="334" height="21"/> <rect key="frame" x="20" y="11" width="334" height="22"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" spellCheckingType="no" keyboardType="emailAddress" textContentType="username"/> <textInputTraits key="textInputTraits" spellCheckingType="no" keyboardType="emailAddress" textContentType="username"/>
</textField> </textField>
@ -315,7 +315,7 @@
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/> <textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/>
</textField> </textField>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TfW-wf-V06"> <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" pointerInteraction="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TfW-wf-V06">
<rect key="frame" x="311" y="5.5" width="43" height="33"/> <rect key="frame" x="311" y="5.5" width="43" height="33"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/> <fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<state key="normal" title="Show"/> <state key="normal" title="Show"/>

View File

@ -12,7 +12,7 @@ import Account
import RSTree import RSTree
protocol MasterFeedTableViewCellDelegate: class { protocol MasterFeedTableViewCellDelegate: class {
func disclosureSelected(_ sender: MasterFeedTableViewCell, expanding: Bool) func masterFeedTableViewCellDisclosureDidToggle(_ sender: MasterFeedTableViewCell, expanding: Bool)
} }
class MasterFeedTableViewCell : VibrantTableViewCell { class MasterFeedTableViewCell : VibrantTableViewCell {
@ -149,7 +149,7 @@ class MasterFeedTableViewCell : VibrantTableViewCell {
@objc func buttonPressed(_ sender: UIButton) { @objc func buttonPressed(_ sender: UIButton) {
if isDisclosureAvailable { if isDisclosureAvailable {
setDisclosure(isExpanded: !isDisclosureExpanded, animated: true) setDisclosure(isExpanded: !isDisclosureExpanded, animated: true)
delegate?.disclosureSelected(self, expanding: isDisclosureExpanded) delegate?.masterFeedTableViewCellDisclosureDidToggle(self, expanding: isDisclosureExpanded)
} }
} }
@ -181,6 +181,9 @@ private extension MasterFeedTableViewCell {
disclosureButton?.tintColor = AppAssets.controlBackgroundColor disclosureButton?.tintColor = AppAssets.controlBackgroundColor
disclosureButton?.imageView?.contentMode = .center disclosureButton?.imageView?.contentMode = .center
disclosureButton?.imageView?.clipsToBounds = false disclosureButton?.imageView?.clipsToBounds = false
if #available(iOS 13.4, *) {
disclosureButton?.isPointerInteractionEnabled = true
}
addSubviewAtInit(disclosureButton!) addSubviewAtInit(disclosureButton!)
} }

View File

@ -8,8 +8,14 @@
import UIKit import UIKit
protocol MasterFeedTableViewSectionHeaderDelegate {
func masterFeedTableViewSectionHeaderDisclosureDidToggle(_ sender: MasterFeedTableViewSectionHeader)
}
class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
var delegate: MasterFeedTableViewSectionHeaderDelegate?
override var accessibilityLabel: String? { override var accessibilityLabel: String? {
set {} set {}
get { get {
@ -66,12 +72,16 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
}() }()
private let unreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero) private let unreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero)
private var disclosureView: UIImageView = { private lazy var disclosureButton: UIButton = {
let iView = NonIntrinsicImageView() let button = NonIntrinsicButton()
iView.tintColor = UIColor.tertiaryLabel button.tintColor = UIColor.tertiaryLabel
iView.image = AppAssets.disclosureImage button.setImage(AppAssets.disclosureImage, for: .normal)
iView.contentMode = .center button.contentMode = .center
return iView if #available(iOS 13.4, *) {
button.isPointerInteractionEnabled = true
}
button.addTarget(self, action: #selector(toggleDisclosure), for: .touchUpInside)
return button
}() }()
private let topSeparatorView: UIView = { private let topSeparatorView: UIView = {
@ -115,10 +125,14 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
private extension MasterFeedTableViewSectionHeader { private extension MasterFeedTableViewSectionHeader {
@objc func toggleDisclosure() {
delegate?.masterFeedTableViewSectionHeaderDisclosureDidToggle(self)
}
func commonInit() { func commonInit() {
addSubviewAtInit(unreadCountView) addSubviewAtInit(unreadCountView)
addSubviewAtInit(titleView) addSubviewAtInit(titleView)
addSubviewAtInit(disclosureView) addSubviewAtInit(disclosureButton)
updateExpandedState(animate: false) updateExpandedState(animate: false)
addBackgroundView() addBackgroundView()
addSubviewAtInit(topSeparatorView) addSubviewAtInit(topSeparatorView)
@ -136,9 +150,9 @@ private extension MasterFeedTableViewSectionHeader {
withDuration: duration, withDuration: duration,
animations: { animations: {
if self.disclosureExpanded { if self.disclosureExpanded {
self.disclosureView.transform = CGAffineTransform(rotationAngle: 1.570796) self.disclosureButton.transform = CGAffineTransform(rotationAngle: 1.570796)
} else { } else {
self.disclosureView.transform = CGAffineTransform(rotationAngle: 0) self.disclosureButton.transform = CGAffineTransform(rotationAngle: 0)
} }
}, completion: { _ in }, completion: { _ in
if !self.isLastSection && !self.disclosureExpanded { if !self.isLastSection && !self.disclosureExpanded {
@ -167,7 +181,7 @@ private extension MasterFeedTableViewSectionHeader {
func layoutWith(_ layout: MasterFeedTableViewSectionHeaderLayout) { func layoutWith(_ layout: MasterFeedTableViewSectionHeaderLayout) {
titleView.setFrameIfNotEqual(layout.titleRect) titleView.setFrameIfNotEqual(layout.titleRect)
unreadCountView.setFrameIfNotEqual(layout.unreadCountRect) unreadCountView.setFrameIfNotEqual(layout.unreadCountRect)
disclosureView.setFrameIfNotEqual(layout.disclosureButtonRect) disclosureButton.setFrameIfNotEqual(layout.disclosureButtonRect)
let top = CGRect(x: safeAreaInsets.left, y: 0, width: frame.width - safeAreaInsets.right - safeAreaInsets.left, height: 0.33) let top = CGRect(x: safeAreaInsets.left, y: 0, width: frame.width - safeAreaInsets.right - safeAreaInsets.left, height: 0.33)
topSeparatorView.setFrameIfNotEqual(top) topSeparatorView.setFrameIfNotEqual(top)

View File

@ -158,6 +158,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
} }
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! MasterFeedTableViewSectionHeader let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! MasterFeedTableViewSectionHeader
headerView.delegate = self
headerView.name = nameProvider.nameForDisplay headerView.name = nameProvider.nameForDisplay
guard let sectionNode = coordinator.rootNode.childAtIndex(section) else { guard let sectionNode = coordinator.rootNode.childAtIndex(section) else {
@ -386,24 +387,10 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
} }
@objc func toggleSectionHeader(_ sender: UITapGestureRecognizer) { @objc func toggleSectionHeader(_ sender: UITapGestureRecognizer) {
guard let headerView = sender.view as? MasterFeedTableViewSectionHeader else {
guard let sectionIndex = sender.view?.tag, return
let sectionNode = coordinator.rootNode.childAtIndex(sectionIndex),
let headerView = sender.view as? MasterFeedTableViewSectionHeader
else {
return
} }
toggle(headerView)
if coordinator.isExpanded(sectionNode) {
headerView.disclosureExpanded = false
coordinator.collapse(sectionNode)
self.applyChanges(animated: true)
} else {
headerView.disclosureExpanded = true
coordinator.expand(sectionNode)
self.applyChanges(animated: true)
}
} }
@objc func refreshAccounts(_ sender: Any) { @objc func refreshAccounts(_ sender: Any) {
@ -556,11 +543,21 @@ extension MasterFeedViewController: UIContextMenuInteractionDelegate {
} }
} }
// MARK: MasterFeedTableViewSectionHeaderDelegate
extension MasterFeedViewController: MasterFeedTableViewSectionHeaderDelegate {
func masterFeedTableViewSectionHeaderDisclosureDidToggle(_ sender: MasterFeedTableViewSectionHeader) {
toggle(sender)
}
}
// MARK: MasterTableViewCellDelegate // MARK: MasterTableViewCellDelegate
extension MasterFeedViewController: MasterFeedTableViewCellDelegate { extension MasterFeedViewController: MasterFeedTableViewCellDelegate {
func disclosureSelected(_ sender: MasterFeedTableViewCell, expanding: Bool) { func masterFeedTableViewCellDisclosureDidToggle(_ sender: MasterFeedTableViewCell, expanding: Bool) {
if expanding { if expanding {
expand(sender) expand(sender)
} else { } else {
@ -753,6 +750,22 @@ private extension MasterFeedViewController {
return nil return nil
} }
func toggle(_ headerView: MasterFeedTableViewSectionHeader) {
guard let sectionNode = coordinator.rootNode.childAtIndex(headerView.tag) else {
return
}
if coordinator.isExpanded(sectionNode) {
headerView.disclosureExpanded = false
coordinator.collapse(sectionNode)
self.applyChanges(animated: true)
} else {
headerView.disclosureExpanded = true
coordinator.expand(sectionNode)
self.applyChanges(animated: true)
}
}
func expand(_ cell: MasterFeedTableViewCell) { func expand(_ cell: MasterFeedTableViewCell) {
guard let indexPath = tableView.indexPath(for: cell), let node = dataSource.itemIdentifier(for: indexPath) else { guard let indexPath = tableView.indexPath(for: cell), let node = dataSource.itemIdentifier(for: indexPath) else {
return return