Make special layout for Account rows (Section Headers). Issue #1253
This commit is contained in:
parent
d4f9e73438
commit
8efd94e24d
|
@ -88,6 +88,7 @@
|
||||||
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */; };
|
516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */; };
|
||||||
516A09402361240900EAE89B /* Account.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A093F2361240900EAE89B /* Account.storyboard */; };
|
516A09402361240900EAE89B /* Account.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A093F2361240900EAE89B /* Account.storyboard */; };
|
||||||
516A09422361248000EAE89B /* Inspector.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A09412361248000EAE89B /* Inspector.storyboard */; };
|
516A09422361248000EAE89B /* Inspector.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 516A09412361248000EAE89B /* Inspector.storyboard */; };
|
||||||
|
516AE9B32371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516AE9B22371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift */; };
|
||||||
51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */; };
|
51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */; };
|
||||||
5170743A232AABFC00A461A3 /* FlattenedAccountFolderPickerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452812265093600C03939 /* FlattenedAccountFolderPickerData.swift */; };
|
5170743A232AABFC00A461A3 /* FlattenedAccountFolderPickerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452812265093600C03939 /* FlattenedAccountFolderPickerData.swift */; };
|
||||||
517630042336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
|
517630042336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
|
||||||
|
@ -1251,6 +1252,7 @@
|
||||||
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsTableViewCell.xib; sourceTree = "<group>"; };
|
516A093A2360A4A000EAE89B /* SettingsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsTableViewCell.xib; sourceTree = "<group>"; };
|
||||||
516A093F2361240900EAE89B /* Account.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Account.storyboard; sourceTree = "<group>"; };
|
516A093F2361240900EAE89B /* Account.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Account.storyboard; sourceTree = "<group>"; };
|
||||||
516A09412361248000EAE89B /* Inspector.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Inspector.storyboard; sourceTree = "<group>"; };
|
516A09412361248000EAE89B /* Inspector.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Inspector.storyboard; sourceTree = "<group>"; };
|
||||||
|
516AE9B22371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterFeedTableViewSectionHeaderLayout.swift; sourceTree = "<group>"; };
|
||||||
51707438232AA97100A461A3 /* ShareFolderPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerController.swift; sourceTree = "<group>"; };
|
51707438232AA97100A461A3 /* ShareFolderPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerController.swift; sourceTree = "<group>"; };
|
||||||
517630032336215100E15FFF /* main.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
|
517630032336215100E15FFF /* main.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
|
||||||
517630222336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleViewControllerWebViewProvider.swift; sourceTree = "<group>"; };
|
517630222336657E00E15FFF /* ArticleViewControllerWebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleViewControllerWebViewProvider.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1869,6 +1871,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
512E08F722688F7C00BDCFDD /* MasterFeedTableViewSectionHeader.swift */,
|
512E08F722688F7C00BDCFDD /* MasterFeedTableViewSectionHeader.swift */,
|
||||||
|
516AE9B22371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift */,
|
||||||
51C45262226508F600C03939 /* MasterFeedTableViewCell.swift */,
|
51C45262226508F600C03939 /* MasterFeedTableViewCell.swift */,
|
||||||
51C45263226508F600C03939 /* MasterFeedTableViewCellLayout.swift */,
|
51C45263226508F600C03939 /* MasterFeedTableViewCellLayout.swift */,
|
||||||
51C45261226508F600C03939 /* MasterFeedUnreadCountView.swift */,
|
51C45261226508F600C03939 /* MasterFeedUnreadCountView.swift */,
|
||||||
|
@ -3970,6 +3973,7 @@
|
||||||
518651DA235621840078E021 /* ImageTransition.swift in Sources */,
|
518651DA235621840078E021 /* ImageTransition.swift in Sources */,
|
||||||
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
|
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
|
||||||
51A16997235E10D700EB091F /* RefreshIntervalViewController.swift in Sources */,
|
51A16997235E10D700EB091F /* RefreshIntervalViewController.swift in Sources */,
|
||||||
|
516AE9B32371C372007DEEAA /* MasterFeedTableViewSectionHeaderLayout.swift in Sources */,
|
||||||
51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */,
|
51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */,
|
||||||
84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */,
|
84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */,
|
||||||
512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */,
|
512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */,
|
||||||
|
|
|
@ -98,26 +98,14 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||||
|
let layout = MasterFeedTableViewSectionHeaderLayout(cellWidth: size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView)
|
||||||
let unreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero)
|
|
||||||
|
|
||||||
// Since we can't reload Section Headers to reset the height after we get the
|
|
||||||
// unread count did change, we always assume a large unread count
|
|
||||||
//
|
|
||||||
// This means that sometimes on the second to largest font size will have extra
|
|
||||||
// space under the account name. This is better than having it overflow into the
|
|
||||||
// cell below.
|
|
||||||
unreadCountView.unreadCount = 888
|
|
||||||
|
|
||||||
let layout = MasterFeedTableViewCellLayout(cellWidth: size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: false, indent: false, shouldShowDisclosure: true)
|
|
||||||
|
|
||||||
return CGSize(width: bounds.width, height: layout.height)
|
return CGSize(width: bounds.width, height: layout.height)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func layoutSubviews() {
|
override func layoutSubviews() {
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
let layout = MasterFeedTableViewCellLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView, showingEditingControl: false, indent: false, shouldShowDisclosure: true)
|
let layout = MasterFeedTableViewSectionHeaderLayout(cellWidth: bounds.size.width, insets: safeAreaInsets, label: titleView, unreadCountView: unreadCountView)
|
||||||
layoutWith(layout)
|
layoutWith(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +159,7 @@ private extension MasterFeedTableViewSectionHeader {
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func layoutWith(_ layout: MasterFeedTableViewCellLayout) {
|
func layoutWith(_ layout: MasterFeedTableViewSectionHeaderLayout) {
|
||||||
titleView.setFrameIfNotEqual(layout.titleRect)
|
titleView.setFrameIfNotEqual(layout.titleRect)
|
||||||
unreadCountView.setFrameIfNotEqual(layout.unreadCountRect)
|
unreadCountView.setFrameIfNotEqual(layout.unreadCountRect)
|
||||||
disclosureView.setFrameIfNotEqual(layout.disclosureButtonRect)
|
disclosureView.setFrameIfNotEqual(layout.disclosureButtonRect)
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
//
|
||||||
|
// MasterFeedTableViewSectionHeaderLayout.swift
|
||||||
|
// NetNewsWire-iOS
|
||||||
|
//
|
||||||
|
// Created by Maurice Parker on 11/5/19.
|
||||||
|
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import RSCore
|
||||||
|
|
||||||
|
struct MasterFeedTableViewSectionHeaderLayout {
|
||||||
|
|
||||||
|
private static let labelMarginRight = CGFloat(integerLiteral: 8)
|
||||||
|
private static let unreadCountMarginRight = CGFloat(integerLiteral: 16)
|
||||||
|
private static let disclosureButtonSize = CGSize(width: 44, height: 44)
|
||||||
|
private static let verticalPadding = CGFloat(integerLiteral: 11)
|
||||||
|
|
||||||
|
private static let minRowHeight = CGFloat(integerLiteral: 44)
|
||||||
|
|
||||||
|
let titleRect: CGRect
|
||||||
|
let unreadCountRect: CGRect
|
||||||
|
let disclosureButtonRect: CGRect
|
||||||
|
|
||||||
|
let height: CGFloat
|
||||||
|
|
||||||
|
init(cellWidth: CGFloat, insets: UIEdgeInsets, label: UILabel, unreadCountView: MasterFeedUnreadCountView) {
|
||||||
|
|
||||||
|
let bounds = CGRect(x: insets.left, y: 0.0, width: floor(cellWidth - insets.right), height: 0.0)
|
||||||
|
|
||||||
|
// Disclosure Button
|
||||||
|
var rDisclosure = CGRect.zero
|
||||||
|
rDisclosure.size = MasterFeedTableViewSectionHeaderLayout.disclosureButtonSize
|
||||||
|
rDisclosure.origin.x = bounds.origin.x
|
||||||
|
|
||||||
|
// Unread Count
|
||||||
|
let unreadCountSize = unreadCountView.contentSize
|
||||||
|
let unreadCountIsHidden = unreadCountView.unreadCount < 1
|
||||||
|
|
||||||
|
var rUnread = CGRect.zero
|
||||||
|
if !unreadCountIsHidden {
|
||||||
|
rUnread.size = unreadCountSize
|
||||||
|
rUnread.origin.x = bounds.maxX - (MasterFeedTableViewSectionHeaderLayout.unreadCountMarginRight + unreadCountSize.width)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max Unread Count
|
||||||
|
// We can't reload Section Headers so we don't let the title extend into the (probably) worse case Unread Count area.
|
||||||
|
let maxUnreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero)
|
||||||
|
maxUnreadCountView.unreadCount = 888
|
||||||
|
let maxUnreadCountSize = maxUnreadCountView.contentSize
|
||||||
|
|
||||||
|
// Title
|
||||||
|
let rLabelx = insets.left + MasterFeedTableViewSectionHeaderLayout.disclosureButtonSize.width
|
||||||
|
let rLabely = UIFontMetrics.default.scaledValue(for: MasterFeedTableViewSectionHeaderLayout.verticalPadding)
|
||||||
|
|
||||||
|
var labelWidth = CGFloat.zero
|
||||||
|
labelWidth = cellWidth - (rLabelx + MasterFeedTableViewSectionHeaderLayout.labelMarginRight + maxUnreadCountSize.width + MasterFeedTableViewSectionHeaderLayout.unreadCountMarginRight)
|
||||||
|
|
||||||
|
let labelSizeInfo = MultilineUILabelSizer.size(for: label.text ?? "", font: label.font, numberOfLines: 0, width: Int(floor(labelWidth)))
|
||||||
|
let rLabel = CGRect(x: rLabelx, y: rLabely, width: labelWidth, height: labelSizeInfo.size.height)
|
||||||
|
|
||||||
|
// Determine cell height
|
||||||
|
let paddedLabelHeight = rLabel.maxY + UIFontMetrics.default.scaledValue(for: MasterFeedTableViewSectionHeaderLayout.verticalPadding)
|
||||||
|
let maxGraphicsHeight = [rUnread, rDisclosure].maxY()
|
||||||
|
var cellHeight = max(paddedLabelHeight, maxGraphicsHeight)
|
||||||
|
if cellHeight < MasterFeedTableViewSectionHeaderLayout.minRowHeight {
|
||||||
|
cellHeight = MasterFeedTableViewSectionHeaderLayout.minRowHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center in Cell
|
||||||
|
let newBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width, height: cellHeight)
|
||||||
|
if !unreadCountIsHidden {
|
||||||
|
rUnread = MasterFeedTableViewCellLayout.centerVertically(rUnread, newBounds)
|
||||||
|
}
|
||||||
|
rDisclosure = MasterFeedTableViewCellLayout.centerVertically(rDisclosure, newBounds)
|
||||||
|
|
||||||
|
// Assign the properties
|
||||||
|
self.height = cellHeight
|
||||||
|
self.unreadCountRect = rUnread
|
||||||
|
self.disclosureButtonRect = rDisclosure
|
||||||
|
self.titleRect = rLabel
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue