Skip to content

Commit

Permalink
add support for action button in notification bar (microsoft#134)
Browse files Browse the repository at this point in the history
- make sure message text style for bar is adhere to latest design
- messageText is natural align when there is an action button but center if it is a simple bar
- add demo example of persistent bar with action button
  • Loading branch information
harrieshin authored Jul 24, 2020
1 parent c041509 commit 256994f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class NotificationViewDemoController: DemoController {
case primaryBar
case primaryOutlineBar
case neutralBar
case persistentBarWithAction
case persistentBarWithCancel

var displayText: String {
switch self {
Expand All @@ -28,6 +30,10 @@ class NotificationViewDemoController: DemoController {
return "Primary Outline Bar"
case .neutralBar:
return "Neutral Bar"
case .persistentBarWithAction:
return "Persistent Bar with Action"
case .persistentBarWithCancel:
return "Persistent Bar with Cancel"
}
}

Expand Down Expand Up @@ -73,6 +79,10 @@ class NotificationViewDemoController: DemoController {
view.setup(style: .primaryOutlineBar, message: "Mail Sent")
case .neutralBar:
view.setup(style: .neutralBar, message: "No internet connection")
case .persistentBarWithAction:
view.setup(style: .neutralBar, message: "This error can be taken action on with the action on the right.", actionTitle: "Action", action: { [unowned self] in self.showMessage("`Action` tapped") })
case .persistentBarWithCancel:
view.setup(style: .neutralBar, message: "This error can be tapped or dismissed with the icon to the right.", action: { [unowned self] in self.showMessage("`Dismiss` tapped") })
}
return view
}
Expand Down
49 changes: 27 additions & 22 deletions ios/FluentUI/Notification/NotificationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ open class NotificationView: UIView {
}

var cornerRadius: CGFloat { return isToast ? Constants.cornerRadiusForToast : 0 }
var messageAlignment: NSTextAlignment { return isToast ? .natural : .center }
var messageStyle: TextStyle { return isToast ? Constants.messageTextStyle : Constants.messageTextStyleForBar }
var presentationOffset: CGFloat { return isToast ? Constants.presentationOffsetForToast : 0 }
var needsFullWidth: Bool { return !isToast }

Expand All @@ -93,7 +91,8 @@ open class NotificationView: UIView {
var needsSeparator: Bool { return self == .primaryOutlineBar }
var supportsTitle: Bool { return isToast }
var supportsImage: Bool { return isToast }
var supportsAction: Bool { return isToast }
var supportsMessageAction: Bool { return isToast }
var shouldAlwaysShowActionButton: Bool { return isToast }

private func primaryFilledBackground(for window: UIWindow) -> UIColor {
let primaryColor = Colors.primary(for: window)
Expand All @@ -114,7 +113,6 @@ open class NotificationView: UIView {

static let titleTextStyle: TextStyle = .button1
static let messageTextStyle: TextStyle = .subhead
static let messageTextStyleForBar: TextStyle = .button1
static let actionButtonTextStyle: TextStyle = .button1

static let animationDurationForShowToast: TimeInterval = 0.6
Expand Down Expand Up @@ -261,18 +259,16 @@ open class NotificationView: UIView {
/// - title: The title text that is shown on the top of the view (only supported in toasts).
/// - message: The message text that is shown below title (if present) or vertically centered in the view.
/// - image: The image that is shown at the leading edge of the view (only supported in toasts).
/// - actionTitle: The title for action on the trailing edge of the view (only supported in toasts).
/// - action: The closure to be called when action button is tapped by a user (only supported in toasts).
/// - actionTitle: The title for action on the trailing edge of the view.
/// - action: The closure to be called when action button is tapped by a user.
/// - messageAction: The closure to be called when the body of the view (except action button) is tapped by a user (only supported in toasts).
/// - Returns: Reference to this view that can be used for "chained" calling of `show`. Can be ignored.
@discardableResult
@objc open func setup(style: Style, title: String = "", message: String, image: UIImage? = nil, actionTitle: String = "", action: (() -> Void)? = nil, messageAction: (() -> Void)? = nil) -> Self {
self.style = style
let title = style.supportsTitle ? title : ""
let image = style.supportsImage ? image : nil
let actionTitle = style.supportsAction ? actionTitle : ""
let action = style.supportsAction ? action : nil
let messageAction = style.supportsAction ? messageAction : nil
let messageAction = style.supportsMessageAction ? messageAction : nil

titleLabel.text = title
titleLabel.isHidden = title.isEmpty
Expand All @@ -281,16 +277,22 @@ open class NotificationView: UIView {
imageView.image = image?.renderingMode == .automatic ? image?.withRenderingMode(.alwaysTemplate) : image
imageView.isHidden = image == nil

if actionTitle.isEmpty {
let actionImage = UIImage.staticImageNamed("dismiss-20x20")
actionImage?.accessibilityLabel = "Accessibility.Dismiss.Label".localized
actionButton.setImage(actionImage, for: .normal)
actionButton.setTitle(nil, for: .normal)
if action != nil || style.shouldAlwaysShowActionButton {
if actionTitle.isEmpty {
let actionImage = UIImage.staticImageNamed("dismiss-20x20")
actionImage?.accessibilityLabel = "Accessibility.Dismiss.Label".localized
actionButton.setImage(actionImage, for: .normal)
actionButton.setTitle(nil, for: .normal)
} else {
actionButton.setImage(nil, for: .normal)
actionButton.setTitle(actionTitle, for: .normal)
}
actionButton.isHidden = false
messageLabel.textAlignment = .natural
} else {
actionButton.setImage(nil, for: .normal)
actionButton.setTitle(actionTitle, for: .normal)
actionButton.isHidden = true
messageLabel.textAlignment = .center
}
actionButton.isHidden = actionTitle.isEmpty && action == nil

self.action = action
self.messageAction = messageAction
Expand Down Expand Up @@ -438,8 +440,13 @@ open class NotificationView: UIView {

open override func sizeThatFits(_ size: CGSize) -> CGSize {
var suggestedWidth: CGFloat = size.width
var availableLabelWidth = suggestedWidth

if !style.needsFullWidth {
if style.needsFullWidth {
if let windowWidth = window?.safeAreaLayoutGuide.layoutFrame.width {
availableLabelWidth = windowWidth
}
} else {
if let windowWidth = window?.frame.width {
suggestedWidth = windowWidth
}
Expand All @@ -453,9 +460,10 @@ open class NotificationView: UIView {
suggestedWidth -= (safeAreaInsets.left + safeAreaInsets.right + 2 * style.presentationOffset)
}
suggestedWidth = ceil(suggestedWidth)
availableLabelWidth = suggestedWidth
}

var availableLabelWidth = suggestedWidth - 2 * Constants.horizontalPadding
availableLabelWidth -= (2 * Constants.horizontalPadding)
if !actionButton.isHidden {
let actionButtonSize = actionButton.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
availableLabelWidth -= (actionButtonSize.width + Constants.horizontalSpacing)
Expand Down Expand Up @@ -500,9 +508,6 @@ open class NotificationView: UIView {
}
separator.isHidden = !style.needsSeparator

messageLabel.textAlignment = style.messageAlignment
messageLabel.style = style.messageStyle

updateWindowSpecificColors()
}

Expand Down

0 comments on commit 256994f

Please sign in to comment.