Skip to content

Commit

Permalink
Reapply #1929 and fix issue where header title uses incorrect font (#…
Browse files Browse the repository at this point in the history
…2040)

* TableViewHeaderFooterView should not override any font or color provided as part of the AttributedString (#1929)

* Update CommandBarButton.swift

* Update CommandBarButton.swift

* Command handled event should pass the event source in the handler

* Fix spacing

* Fix lint errors and make updates for some review comments

* Do not override font or color provided in the attributed string

* Fix spacing

* Fix update of titleView font

* Updates for PR feedback

* Only use attributed color and font when non-nil, otherwise use tokenset value

* Cleanup setup methods. Move all setup to setupBase(...) to ensure views are correctly recycled when reused.

* More cleanup

* fixups

* PR Updates

---------

Co-authored-by: owenconnolly <52223389+owenconnolly@users.noreply.github.com>
  • Loading branch information
nodes11 and owenconnolly committed Jun 21, 2024
1 parent a7c83b5 commit 744a205
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ extension TableViewHeaderFooterViewDemoController {
if section.footerLinkText.isEmpty {
footer?.setup(style: .footer, title: section.footerText)
} else {
let title = NSMutableAttributedString(string: section.footerText)
let title = NSMutableAttributedString(string: section.footerText, attributes: [NSAttributedString.Key.foregroundColor: footer?.tokenSet[.textColor].uiColor ?? .white])
let range = (title.string as NSString).range(of: section.footerLinkText)
if range.location != -1 {
title.addAttribute(.link, value: "https://github.com/microsoft/fluentui-apple", range: range)
Expand Down
73 changes: 51 additions & 22 deletions ios/FluentUI/Table View/TableViewHeaderFooterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
/// - title: The title string.
/// - accessoryButtonTitle: Optional accessory button title string.
@objc open func setup(style: Style, title: String, accessoryButtonTitle: String = "") {
setup(style: style, title: title, accessoryButtonTitle: accessoryButtonTitle, leadingView: nil)
setupBase(style: style, title: title, accessoryButtonTitle: accessoryButtonTitle)
}

/// - Parameters:
Expand All @@ -253,19 +253,15 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
/// - accessoryButtonTitle: Optional accessory button title string.
/// - leadingView: An optional custom view that appears near the leading edge of the view.
@objc open func setup(style: Style, title: String, accessoryButtonTitle: String = "", leadingView: UIView? = nil) {
titleView.attributedText = NSAttributedString(string: " ") // to clear attributes
titleView.text = title
titleView.isSelectable = false

setup(style: style, accessoryButtonTitle: accessoryButtonTitle, leadingView: leadingView)
setupBase(style: style, title: title, accessoryButtonTitle: accessoryButtonTitle, leadingView: leadingView)
}

/// - Parameters:
/// - style: The `TableViewHeaderFooterView.Style` used to set up the view.
/// - attributedTitle: Title as an NSAttributedString for additional attributes.
/// - accessoryButtonTitle: Optional accessory button title string.
@objc open func setup(style: Style, attributedTitle: NSAttributedString, accessoryButtonTitle: String = "") {
setup(style: style, attributedTitle: attributedTitle, accessoryButtonTitle: accessoryButtonTitle, leadingView: nil)
setupBase(style: style, attributedTitle: attributedTitle, accessoryButtonTitle: accessoryButtonTitle)
}

/// - Parameters:
Expand All @@ -274,18 +270,15 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
/// - accessoryButtonTitle: Optional accessory button title string.
/// - leadingView: An optional custom view that appears near the leading edge of the view.
@objc open func setup(style: Style, attributedTitle: NSAttributedString, accessoryButtonTitle: String = "", leadingView: UIView? = nil) {
titleView.attributedText = attributedTitle
titleView.isSelectable = true

setup(style: style, accessoryButtonTitle: accessoryButtonTitle, leadingView: leadingView)
setupBase(style: style, attributedTitle: attributedTitle, accessoryButtonTitle: accessoryButtonTitle, leadingView: leadingView)
}

/// - Parameters:
/// - style: The `TableViewHeaderFooterView.Style` used to set up the view.
/// - title: The title string.
/// - accessoryView: The optional custom accessory view in the trailing edge of this view.
@objc open func setup(style: Style, title: String, accessoryView: UIView) {
setup(style: style, title: title, accessoryView: accessoryView, leadingView: nil)
setupBase(style: style, title: title, accessoryView: accessoryView)
}

/// - Parameters:
Expand All @@ -296,30 +289,48 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
/// If `accessoryView` is set, the accessory button (if any) will be replaced by this custom view. Clients are responsible
/// for the appearance and behavior of both the `accessoryView` and `leadingView`, including event handling and accessibility.
@objc open func setup(style: Style, title: String, accessoryView: UIView, leadingView: UIView? = nil) {
setup(style: style, title: title, accessoryButtonTitle: "")
self.accessoryView = accessoryView
self.leadingView = leadingView
setupBase(style: style, title: title, accessoryView: accessoryView, leadingView: leadingView)
}

/// - Parameters:
/// - style: The `TableViewHeaderFooterView.Style` used to set up the view.
/// - accessoryButtonTitle: Optional accessory button title string.
@objc open func setup(style: Style, accessoryButtonTitle: String) {
setup(style: style, accessoryButtonTitle: accessoryButtonTitle, leadingView: nil)
setupBase(style: style, accessoryButtonTitle: accessoryButtonTitle)
}

/// - Parameters:
/// - style: The `TableViewHeaderFooterView.Style` used to set up the view.
/// - title: The title string.
@objc open func setup(style: Style, title: String) {
setup(style: style, title: title, accessoryButtonTitle: "")
setupBase(style: style, title: title)
}

/// This is the base setup method. All other setup methods call this method with their parameters.
/// - Parameters:
/// - style: The `TableViewHeaderFooterView.Style` used to set up the view.
/// - title: The title string
/// - attributedTitle: Title as an NSAttributedString for additional attributes.
/// - accessoryButtonTitle: Optional accessory button title string.
/// - accessoryView: The optional custom accessory view in the trailing edge of this view.
/// - leadingView: An optional custom view that appears near the leading edge of the view.
private func setup(style: Style, accessoryButtonTitle: String, leadingView: UIView? = nil) {
private func setupBase(style: Style,
title: String? = nil,
attributedTitle: NSAttributedString? = nil,
accessoryButtonTitle: String = "",
accessoryView: UIView? = nil,
leadingView: UIView? = nil) {
if let attributedTitle {
self.attributedTitle = attributedTitle
titleView.attributedText = attributedTitle
titleView.isSelectable = true
} else {
self.attributedTitle = nil
titleView.attributedText = NSAttributedString(string: " ") // to clear attributes
titleView.text = title
titleView.isSelectable = false
}

updateTitleViewFont()
switch style {
case .header, .headerPrimary:
Expand All @@ -329,6 +340,12 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
}

accessoryButton = !accessoryButtonTitle.isEmpty ? createAccessoryButton(withTitle: accessoryButtonTitle) : nil

/// `accessoryButton` and `accessoryView` occupy the same space at the trailing end of the view. If both are provided, the `accessoryView` will be given priority
if accessoryView != nil {
self.accessoryView = accessoryView
}

self.leadingView = leadingView

self.style = style
Expand Down Expand Up @@ -437,7 +454,10 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
private func updateTitleViewFont() {
if let window = window {
let titleFont = tokenSet[.textFont].uiFont
titleView.font = titleFont
if !isUsingAttributedTitle {
titleView.font = titleFont
}

// offset text container to center its content
#if os(iOS)
let scale = window.rootViewController?.view.contentScaleFactor ?? window.screen.scale
Expand All @@ -451,8 +471,6 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
}

private func updateTitleAndBackgroundColors() {
titleView.textColor = tokenSet[.textColor].uiColor

if tableViewCellStyle == .grouped {
backgroundView?.backgroundColor = tokenSet[.backgroundColorGrouped].uiColor
} else if tableViewCellStyle == .plain {
Expand All @@ -461,7 +479,10 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
backgroundView?.backgroundColor = .clear
}

titleView.font = tokenSet[.textFont].uiFont
if !isUsingAttributedTitle {
titleView.textColor = tokenSet[.textColor].uiColor
titleView.font = tokenSet[.textFont].uiFont
}
titleView.linkColor = tokenSet[.linkTextColor].uiColor
}

Expand Down Expand Up @@ -500,6 +521,14 @@ open class TableViewHeaderFooterView: UITableViewHeaderFooterView, TokenizedCont
@objc private func handleHeaderViewTapped() {
onHeaderViewTapped?()
}

private var attributedTitle: NSAttributedString? {
didSet {
isUsingAttributedTitle = attributedTitle != nil
}
}

private var isUsingAttributedTitle: Bool = false
}

// MARK: - TableViewHeaderFooterView: UITextViewDelegate
Expand Down

0 comments on commit 744a205

Please sign in to comment.