diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 955a12bb0..1cc18e77a 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -64,7 +64,6 @@ 51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452702265091600C03939 /* MultilineUILabelSizer.swift */; }; 51C452782265091600C03939 /* MasterTimelineCellData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452712265091600C03939 /* MasterTimelineCellData.swift */; }; 51C452792265091600C03939 /* MasterTimelineTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452722265091600C03939 /* MasterTimelineTableViewCell.swift */; }; - 51C4527A2265091600C03939 /* SingleLineUILabelSizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452732265091600C03939 /* SingleLineUILabelSizer.swift */; }; 51C4527B2265091600C03939 /* MasterUnreadIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452742265091600C03939 /* MasterUnreadIndicatorView.swift */; }; 51C4527C2265091600C03939 /* MasterTimelineCellLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C452752265091600C03939 /* MasterTimelineCellLayout.swift */; }; 51C4527F2265092C00C03939 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C4527E2265092C00C03939 /* DetailViewController.swift */; }; @@ -117,6 +116,8 @@ 51F85BF52273625800C787DC /* Bundle-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BF42273625800C787DC /* Bundle-Extensions.swift */; }; 51F85BF722749FA100C787DC /* UIFont-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BF622749FA100C787DC /* UIFont-Extensions.swift */; }; 51F85BF92274AA7B00C787DC /* UIBarButtonItem-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BF82274AA7B00C787DC /* UIBarButtonItem-Extensions.swift */; }; + 51F85BFB2275D85000C787DC /* Array-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BFA2275D85000C787DC /* Array-Extensions.swift */; }; + 51F85BFD2275DCA800C787DC /* SingleLineUILabelSizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BFC2275DCA800C787DC /* SingleLineUILabelSizer.swift */; }; 6581C73820CED60100F4AD34 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */; }; 6581C73A20CED60100F4AD34 /* SafariExtensionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6581C73920CED60100F4AD34 /* SafariExtensionViewController.swift */; }; 6581C73D20CED60100F4AD34 /* SafariExtensionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6581C73B20CED60100F4AD34 /* SafariExtensionViewController.xib */; }; @@ -651,7 +652,6 @@ 51C452702265091600C03939 /* MultilineUILabelSizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultilineUILabelSizer.swift; sourceTree = ""; }; 51C452712265091600C03939 /* MasterTimelineCellData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterTimelineCellData.swift; sourceTree = ""; }; 51C452722265091600C03939 /* MasterTimelineTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterTimelineTableViewCell.swift; sourceTree = ""; }; - 51C452732265091600C03939 /* SingleLineUILabelSizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleLineUILabelSizer.swift; sourceTree = ""; }; 51C452742265091600C03939 /* MasterUnreadIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterUnreadIndicatorView.swift; sourceTree = ""; }; 51C452752265091600C03939 /* MasterTimelineCellLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterTimelineCellLayout.swift; sourceTree = ""; }; 51C4527E2265092C00C03939 /* DetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; @@ -672,6 +672,8 @@ 51F85BF42273625800C787DC /* Bundle-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle-Extensions.swift"; sourceTree = ""; }; 51F85BF622749FA100C787DC /* UIFont-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont-Extensions.swift"; sourceTree = ""; }; 51F85BF82274AA7B00C787DC /* UIBarButtonItem-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem-Extensions.swift"; sourceTree = ""; }; + 51F85BFA2275D85000C787DC /* Array-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array-Extensions.swift"; sourceTree = ""; }; + 51F85BFC2275DCA800C787DC /* SingleLineUILabelSizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleLineUILabelSizer.swift; sourceTree = ""; }; 6581C73320CED60000F4AD34 /* Subscribe to Feed.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Subscribe to Feed.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 6581C73420CED60100F4AD34 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 6581C73720CED60100F4AD34 /* SafariExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariExtensionHandler.swift; sourceTree = ""; }; @@ -972,6 +974,7 @@ 51C45245226506C800C03939 /* Extensions */ = { isa = PBXGroup; children = ( + 51F85BFA2275D85000C787DC /* Array-Extensions.swift */, 51F85BF42273625800C787DC /* Bundle-Extensions.swift */, 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */, 5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */, @@ -1021,7 +1024,7 @@ 51C452712265091600C03939 /* MasterTimelineCellData.swift */, 51C452752265091600C03939 /* MasterTimelineCellLayout.swift */, 51C452742265091600C03939 /* MasterUnreadIndicatorView.swift */, - 51C452732265091600C03939 /* SingleLineUILabelSizer.swift */, + 51F85BFC2275DCA800C787DC /* SingleLineUILabelSizer.swift */, 51C452702265091600C03939 /* MultilineUILabelSizer.swift */, ); path = Cell; @@ -2233,6 +2236,7 @@ 51C45291226509C800C03939 /* SmartFeed.swift in Sources */, 51C452A722650A3D00C03939 /* RSImage-Extensions.swift in Sources */, 51C45269226508F600C03939 /* MasterFeedTableViewCell.swift in Sources */, + 51F85BFD2275DCA800C787DC /* SingleLineUILabelSizer.swift in Sources */, 51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */, 5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */, 51C452772265091600C03939 /* MultilineUILabelSizer.swift in Sources */, @@ -2278,11 +2282,11 @@ 5115CAF42266301400B21BCE /* AddContainerViewController.swift in Sources */, 51C45297226509E300C03939 /* DefaultFeedsImporter.swift in Sources */, 512E094D2268B8AB00BDCFDD /* DeleteCommand.swift in Sources */, + 51F85BFB2275D85000C787DC /* Array-Extensions.swift in Sources */, 51C452AC22650FD200C03939 /* AppNotifications.swift in Sources */, 51C452762265091600C03939 /* MasterTimelineViewController.swift in Sources */, 5183CCE9226F68D90010922C /* RefreshTimer.swift in Sources */, 51C452882265093600C03939 /* AddFeedViewController.swift in Sources */, - 51C4527A2265091600C03939 /* SingleLineUILabelSizer.swift in Sources */, 51C4529B22650A1000C03939 /* FaviconDownloader.swift in Sources */, 5183CCE3226F314C0010922C /* ProgressTableViewController.swift in Sources */, 512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */, diff --git a/iOS/Extensions/Array-Extensions.swift b/iOS/Extensions/Array-Extensions.swift new file mode 100644 index 000000000..9a4710680 --- /dev/null +++ b/iOS/Extensions/Array-Extensions.swift @@ -0,0 +1,20 @@ +// +// Array-Extensions.swift +// NetNewsWire-iOS +// +// Created by Maurice Parker on 4/28/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import UIKit + +extension Array where Element == CGRect { + + func maxY() -> CGFloat { + + var y: CGFloat = 0.0 + self.forEach { y = Swift.max(y, $0.maxY) } + return y + } + +} diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift index 0650ed4df..1177a9594 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCell.swift @@ -19,7 +19,8 @@ class MasterFeedTableViewCell : UITableViewCell { weak var delegate: MasterFeedTableViewCellDelegate? var allowDisclosureSelection = false - + private var layout: MasterFeedTableViewCellLayout? + override var accessibilityLabel: String? { set {} get { @@ -52,6 +53,7 @@ class MasterFeedTableViewCell : UITableViewCell { var shouldShowImage = false { didSet { if shouldShowImage != oldValue { + resetLayout() setNeedsLayout() } faviconImageView.image = shouldShowImage ? faviconImage : nil @@ -66,6 +68,7 @@ class MasterFeedTableViewCell : UITableViewCell { if unreadCountView.unreadCount != newValue { unreadCountView.unreadCount = newValue unreadCountView.isHidden = (newValue < 1) + resetLayout() setNeedsLayout() } } @@ -78,6 +81,7 @@ class MasterFeedTableViewCell : UITableViewCell { set { if titleView.text != newValue { titleView.text = newValue + resetLayout() setNeedsDisplay() setNeedsLayout() } @@ -87,7 +91,6 @@ class MasterFeedTableViewCell : UITableViewCell { private let titleView: UILabel = { let label = NonIntrinsicLabel() label.numberOfLines = 0 - label.lineBreakMode = .byTruncatingTail label.allowsDefaultTighteningForTruncation = false label.adjustsFontForContentSizeCategory = true label.font = .preferredFont(forTextStyle: .body) @@ -98,7 +101,7 @@ class MasterFeedTableViewCell : UITableViewCell { return UIImageView(image: AppAssets.feedImage) }() - private let unreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero) + private var unreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero) private var showingEditControl = false private var disclosureButton: UIButton? @@ -107,16 +110,30 @@ class MasterFeedTableViewCell : UITableViewCell { commonInit() } + override func prepareForReuse() { + layout = nil + unreadCountView.setNeedsLayout() + unreadCountView.setNeedsDisplay() + } + override func willTransition(to state: UITableViewCell.StateMask) { super.willTransition(to: state) showingEditControl = state.contains(.showingEditControl) } + override func sizeThatFits(_ size: CGSize) -> CGSize { + if layout == nil { + resetLayout() + } + return CGSize(width: bounds.width, height: layout!.height) + } + override func layoutSubviews() { super.layoutSubviews() - let shouldShowDisclosure = !(showingEditControl && showsReorderControl) - let layout = MasterFeedTableViewCellLayout(cellSize: bounds.size, insets: safeAreaInsets, shouldShowImage: shouldShowImage, label: titleView, unreadCountView: unreadCountView, showingEditingControl: showingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: shouldShowDisclosure) - layoutWith(layout) + if layout == nil { + resetLayout() + } + layoutWith(layout!) } @objc func buttonPressed(_ sender: UIButton) { @@ -168,6 +185,11 @@ private extension MasterFeedTableViewCell { view.translatesAutoresizingMaskIntoConstraints = false } + func resetLayout() { + let shouldShowDisclosure = !(showingEditControl && showsReorderControl) + layout = MasterFeedTableViewCellLayout(cellSize: bounds.size, insets: safeAreaInsets, shouldShowImage: shouldShowImage, label: titleView, unreadCountView: unreadCountView, showingEditingControl: showingEditControl, indent: indentationLevel == 1, shouldShowDisclosure: shouldShowDisclosure) + } + func layoutWith(_ layout: MasterFeedTableViewCellLayout) { faviconImageView.setFrameIfNotEqual(layout.faviconRect) titleView.setFrameIfNotEqual(layout.titleRect) diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift index cb62d0d6c..16c89ac35 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewCellLayout.swift @@ -25,6 +25,8 @@ struct MasterFeedTableViewCellLayout { let unreadCountRect: CGRect let disclosureButtonRect: CGRect + let height: CGFloat + init(cellSize: CGSize, insets: UIEdgeInsets, shouldShowImage: Bool, label: UILabel, unreadCountView: MasterFeedUnreadCountView, showingEditingControl: Bool, indent: Bool, shouldShowDisclosure: Bool) { var initialIndent = MasterFeedTableViewCellLayout.marginLeft + insets.left @@ -41,21 +43,7 @@ struct MasterFeedTableViewCellLayout { var rFavicon = CGRect.zero if shouldShowImage { rFavicon = CGRect(x: bounds.origin.x, y: 0.0, width: MasterFeedTableViewCellLayout.imageSize.width, height: MasterFeedTableViewCellLayout.imageSize.height) - rFavicon = MasterFeedTableViewCellLayout.centerVertically(rFavicon, bounds) } - self.faviconRect = rFavicon - - // Title - let labelSize = SingleLineUILabelSizer.size(for: label.text ?? "", font: label.font!) - - var rLabel = CGRect(x: 0.0, y: 0.0, width: labelSize.width, height: labelSize.height) - if shouldShowImage { - rLabel.origin.x = rFavicon.maxX + MasterFeedTableViewCellLayout.imageMarginRight - } else { - rLabel.origin.x = bounds.minX - } - - rLabel = MasterFeedTableViewCellLayout.centerVertically(rLabel, bounds) // Unread Count let unreadCountSize = unreadCountView.intrinsicContentSize @@ -63,44 +51,54 @@ struct MasterFeedTableViewCellLayout { var rUnread = CGRect.zero if !unreadCountIsHidden { - rUnread.size = unreadCountSize rUnread.origin.x = bounds.maxX - (unreadCountSize.width + MasterFeedTableViewCellLayout.unreadCountMarginRight + MasterFeedTableViewCellLayout.disclosureButtonSize.width) - rUnread = MasterFeedTableViewCellLayout.centerVertically(rUnread, bounds) - - // Cap the Title width based on the unread indicator button - let labelMaxX = rUnread.minX - MasterFeedTableViewCellLayout.unreadCountMarginLeft - if rLabel.maxX > labelMaxX { - rLabel.size.width = labelMaxX - rLabel.minX - } - } - self.unreadCountRect = rUnread // Disclosure Button var rDisclosure = CGRect.zero if shouldShowDisclosure { - rDisclosure.size = MasterFeedTableViewCellLayout.disclosureButtonSize rDisclosure.origin.x = bounds.maxX - MasterFeedTableViewCellLayout.disclosureButtonSize.width - rDisclosure = MasterFeedTableViewCellLayout.centerVertically(rDisclosure, bounds) - - // Cap the Title width based on the disclosure button - let labelMaxX = rDisclosure.minX - if rLabel.maxX > labelMaxX { - rLabel.size.width = labelMaxX - rLabel.minX - } - } - self.disclosureButtonRect = rDisclosure + // Title + let labelWidth = bounds.width - (rFavicon.width + MasterFeedTableViewCellLayout.imageMarginRight + MasterFeedTableViewCellLayout.unreadCountMarginLeft + rUnread.width + MasterFeedTableViewCellLayout.unreadCountMarginRight + rDisclosure.width) + let labelSizeInfo = MultilineUILabelSizer.size(for: label.text ?? "", font: label.font, numberOfLines: 0, width: Int(floor(labelWidth))) - // Cap the Title width based on total width - if rLabel.maxX > bounds.maxX { - rLabel.size.width = bounds.maxX - rLabel.minX + var rLabel = CGRect(x: 0.0, y: 0.0, width: labelSizeInfo.size.width, height: labelSizeInfo.size.height) + if shouldShowImage { + rLabel.origin.x = rFavicon.maxX + MasterFeedTableViewCellLayout.imageMarginRight + } else { + rLabel.origin.x = bounds.minX } + // Determine cell height + let cellHeight = [rFavicon, rLabel, rUnread, rDisclosure].maxY() + + // Center in Cell + let newBounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width, height: cellHeight) + + if shouldShowImage { + rFavicon = MasterFeedTableViewCellLayout.centerVertically(rFavicon, newBounds) + } + + if !unreadCountIsHidden { + rUnread = MasterFeedTableViewCellLayout.centerVertically(rUnread, newBounds) + } + + if shouldShowDisclosure { + rDisclosure = MasterFeedTableViewCellLayout.centerVertically(rDisclosure, newBounds) + } + + rLabel = MasterFeedTableViewCellLayout.centerVertically(rLabel, newBounds) + + // Assign the properties + self.height = cellHeight + self.faviconRect = rFavicon + self.unreadCountRect = rUnread + self.disclosureButtonRect = rDisclosure self.titleRect = rLabel } diff --git a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift index dc2ef8a32..afacf97e3 100644 --- a/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift +++ b/iOS/MasterFeed/Cell/MasterFeedTableViewSectionHeader.swift @@ -10,6 +10,8 @@ import UIKit class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { + private var layout: MasterFeedTableViewCellLayout? + override var accessibilityLabel: String? { set {} get { @@ -57,7 +59,6 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { private let titleView: UILabel = { let label = NonIntrinsicLabel() label.numberOfLines = 0 - label.lineBreakMode = .byTruncatingTail label.allowsDefaultTighteningForTruncation = false label.adjustsFontForContentSizeCategory = true label.font = .preferredFont(forTextStyle: .body) @@ -81,12 +82,20 @@ class MasterFeedTableViewSectionHeader: UITableViewHeaderFooterView { commonInit() } + override func sizeThatFits(_ size: CGSize) -> CGSize { + if layout == nil { + resetLayout() + } + return CGSize(width: bounds.width, height: layout!.height) + } + override func layoutSubviews() { super.layoutSubviews() - let layout = MasterFeedTableViewCellLayout(cellSize: bounds.size, insets: safeAreaInsets, shouldShowImage: false, label: titleView, unreadCountView: unreadCountView, showingEditingControl: false, indent: true, shouldShowDisclosure: true) - layoutWith(layout) + if layout == nil { + resetLayout() + } + layoutWith(layout!) } - } @@ -115,6 +124,10 @@ private extension MasterFeedTableViewSectionHeader { view.translatesAutoresizingMaskIntoConstraints = false } + func resetLayout() { + layout = MasterFeedTableViewCellLayout(cellSize: bounds.size, insets: safeAreaInsets, shouldShowImage: false, label: titleView, unreadCountView: unreadCountView, showingEditingControl: false, indent: true, shouldShowDisclosure: true) + } + func layoutWith(_ layout: MasterFeedTableViewCellLayout) { titleView.setFrameIfNotEqual(layout.titleRect) unreadCountView.setFrameIfNotEqual(layout.unreadCountRect) diff --git a/iOS/MasterFeed/MasterFeedViewController.swift b/iOS/MasterFeed/MasterFeedViewController.swift index bb176ca8c..103dba4a4 100644 --- a/iOS/MasterFeed/MasterFeedViewController.swift +++ b/iOS/MasterFeed/MasterFeedViewController.swift @@ -38,6 +38,7 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn NotificationCenter.default.addObserver(self, selector: #selector(backingStoresDidRebuild(_:)), name: .BackingStoresDidRebuild, object: navState) NotificationCenter.default.addObserver(self, selector: #selector(masterSelectionDidChange(_:)), name: .MasterSelectionDidChange, object: navState) + NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil) refreshControl = UIRefreshControl() refreshControl!.addTarget(self, action: #selector(refreshAccounts(_:)), for: .valueChanged) @@ -141,6 +142,10 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn } } + @objc func contentSizeCategoryDidChange(_ note: Notification) { + tableView.reloadData() + } + // MARK: Table View override func numberOfSections(in tableView: UITableView) -> Int { @@ -152,7 +157,27 @@ class MasterFeedViewController: ProgressTableViewController, UndoableCommandRunn } override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - return CGFloat(integerLiteral: 44) + + guard let nameProvider = navState.rootNode.childAtIndex(section)?.representedObject as? DisplayNameProvider else { + return 44 + } + + let headerView = MasterFeedTableViewSectionHeader() + headerView.name = nameProvider.nameForDisplay + + guard let sectionNode = navState.rootNode.childAtIndex(section) else { + return 44 + } + + if let account = sectionNode.representedObject as? Account { + headerView.unreadCount = account.unreadCount + } else { + headerView.unreadCount = 0 + } + + let size = headerView.sizeThatFits(CGSize.zero) + return size.height + } override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { diff --git a/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift b/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift index 8d0feabd2..a647870d8 100644 --- a/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift +++ b/iOS/MasterTimeline/Cell/MasterTimelineCellLayout.swift @@ -243,14 +243,3 @@ private extension MasterTimelineCellLayout { return r } } - -private extension Array where Element == CGRect { - - func maxY() -> CGFloat { - - var y: CGFloat = 0.0 - self.forEach { y = Swift.max(y, $0.maxY) } - return y - } -} - diff --git a/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift b/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift index fa9a5e918..c5859ba42 100644 --- a/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift +++ b/iOS/MasterTimeline/Cell/MultilineUILabelSizer.swift @@ -98,9 +98,12 @@ private extension MultilineUILabelSizer { } var height = MultilineUILabelSizer.calculateHeight(string, width, font) - let maxHeight = singleLineHeightEstimate * numberOfLines - if height > maxHeight { - height = maxHeight + + if numberOfLines != 0 { + let maxHeight = singleLineHeightEstimate * numberOfLines + if height > maxHeight { + height = maxHeight + } } cache[string]![width] = height