// // MasterTableViewCell.swift // NetNewsWire // // Created by Brent Simmons on 8/1/15. // Copyright © 2015 Ranchero Software, LLC. All rights reserved. // import UIKit import RSCore import Account import RSTree protocol MasterFeedTableViewCellDelegate: class { func disclosureSelected(_ sender: MasterFeedTableViewCell, expanding: Bool) } class MasterFeedTableViewCell : UITableViewCell { weak var delegate: MasterFeedTableViewCellDelegate? var allowDisclosureSelection = false private var layout: MasterFeedTableViewCellLayout? override var accessibilityLabel: String? { set {} get { if unreadCount > 0 { let unreadLabel = NSLocalizedString("unread", comment: "Unread label for accessiblity") return "\(name) \(unreadCount) \(unreadLabel)" } else { return name } } } var disclosureExpanded = false { didSet { updateDisclosureImage() } } var faviconImage: UIImage? { didSet { if let image = faviconImage { faviconImageView.image = shouldShowImage ? image : nil } else { faviconImageView.image = nil } } } var shouldShowImage = false { didSet { if shouldShowImage != oldValue { layout = nil setNeedsLayout() } faviconImageView.image = shouldShowImage ? faviconImage : nil } } var unreadCount: Int { get { return unreadCountView.unreadCount } set { if unreadCountView.unreadCount != newValue { unreadCountView.unreadCount = newValue unreadCountView.isHidden = (newValue < 1) layout = nil setNeedsLayout() } } } var name: String { get { return titleView.text ?? "" } set { if titleView.text != newValue { titleView.text = newValue layout = nil setNeedsLayout() } } } private let titleView: UILabel = { let label = NonIntrinsicLabel() label.numberOfLines = 0 label.allowsDefaultTighteningForTruncation = false label.adjustsFontForContentSizeCategory = true label.font = .preferredFont(forTextStyle: .body) return label }() private let faviconImageView: UIImageView = { return UIImageView(image: AppAssets.feedImage) }() private var unreadCountView = MasterFeedUnreadCountView(frame: CGRect.zero) private var showingEditControl = false private var disclosureButton: UIButton? required init?(coder: NSCoder) { super.init(coder: coder) 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() if layout == nil { resetLayout() } layoutWith(layout!) } @objc func buttonPressed(_ sender: UIButton) { if allowDisclosureSelection { disclosureExpanded = !disclosureExpanded delegate?.disclosureSelected(self, expanding: disclosureExpanded) } } } private extension MasterFeedTableViewCell { func commonInit() { theme() addSubviewAtInit(unreadCountView) addSubviewAtInit(faviconImageView) addSubviewAtInit(titleView) addDisclosureView() } func theme() { let bgView = UIView() bgView.backgroundColor = AppAssets.selectionBackgroundColor selectedBackgroundView = bgView } func addDisclosureView() { disclosureButton = UIButton(type: .roundedRect) disclosureButton!.tintColor = AppAssets.chevronDisclosureColor disclosureButton!.addTarget(self, action: #selector(buttonPressed(_:)), for: UIControl.Event.touchUpInside) updateDisclosureImage() addSubviewAtInit(disclosureButton!) } func updateDisclosureImage() { if disclosureExpanded { disclosureButton?.setImage(AppAssets.chevronDownImage, for: .normal) } else { disclosureButton?.setImage(AppAssets.chevronRightImage, for: .normal) } } func addSubviewAtInit(_ view: UIView) { addSubview(view) view.translatesAutoresizingMaskIntoConstraints = false } func resetLayout() { let shouldShowDisclosure = !(showingEditControl && showsReorderControl) layout = MasterFeedTableViewCellLayout(cellWidth: bounds.size.width, 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) unreadCountView.setFrameIfNotEqual(layout.unreadCountRect) disclosureButton?.setFrameIfNotEqual(layout.disclosureButtonRect) } }