Skip to content

Commit

Permalink
Merge pull request #2252 from CruGlobal/feature/GT-2420-enable-wrappi…
Browse files Browse the repository at this point in the history
…ng-multi-line-text-for-buttons

Feature/gt 2420 enable wrapping multi line text for buttons
  • Loading branch information
levieggertcru authored Aug 16, 2024
2 parents c2716f5 + d51e2c2 commit b46a9e3
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ extension ToolSettingsHostingView: TransparentModalCustomView {

view.translatesAutoresizingMaskIntoConstraints = false

view.constrainLeadingToView(view: parent, constant: modalHorizontalPadding)
view.constrainTrailingToView(view: parent, constant: modalHorizontalPadding)
_ = view.constrainLeadingToView(view: parent, constant: modalHorizontalPadding)
_ = view.constrainTrailingToView(view: parent, constant: modalHorizontalPadding)
modalBottomToParent = view.constrainBottomToView(view: parent, constant: 0)
_ = view.addHeightConstraint(constant: getModalHeight())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ import Foundation
import UIKit

class MobileContentButtonView: MobileContentView {

private static let buttonHeight: CGFloat = 50


private let viewModel: MobileContentButtonViewModel
private let buttonView: UIView = UIView()
private let buttonTitle: UILabel = UILabel()
private let buttonImagePaddingToButtonTitle: CGFloat = 12
private let minimumButtonHeight: CGFloat = 21
private let buttonTopAndBottomPaddingToTitle: CGFloat = 8

private var buttonTitleSizeToFitSize: CGSize?
private var buttonImageView: UIImageView?
private var buttonViewWidthConstraint: NSLayoutConstraint?
private var buttonTitleWidthForIconConstraint: NSLayoutConstraint?

init(viewModel: MobileContentButtonViewModel) {

Expand All @@ -28,6 +30,7 @@ class MobileContentButtonView: MobileContentView {
super.init(viewModel: viewModel, frame: UIScreen.main.bounds)

setupLayout()
addSubviewsAndConstraints(buttonView: buttonView, buttonTitle: buttonTitle, buttonImageView: buttonImageView)
setupBinding()
}

Expand All @@ -42,11 +45,9 @@ class MobileContentButtonView: MobileContentView {
}

private func setupLayout() {

backgroundColor = .clear

let buttonIcon: MobileContentButtonIcon? = viewModel.icon


// buttonView
buttonView.backgroundColor = viewModel.backgroundColor
buttonView.layer.cornerRadius = 5
Expand All @@ -56,63 +57,69 @@ class MobileContentButtonView: MobileContentView {
buttonView.layer.borderWidth = borderWidth
}

// buttonTitle
buttonTitle.isUserInteractionEnabled = false
buttonTitle.backgroundColor = .clear
buttonTitle.numberOfLines = 0
buttonTitle.lineBreakMode = .byWordWrapping
buttonTitle.textAlignment = .center
buttonTitle.font = viewModel.font
buttonTitle.text = viewModel.title
buttonTitle.textColor = viewModel.titleColor

buttonTitle.sizeToFit()
buttonTitleSizeToFitSize = buttonTitle.frame.size

// buttonImageView
if let buttonIcon = viewModel.icon {

let buttonImageView: UIImageView = UIImageView(image: buttonIcon.image)
buttonImageView.isUserInteractionEnabled = false
buttonImageView.backgroundColor = .clear

self.buttonImageView = buttonImageView
}
}

private func addSubviewsAndConstraints(buttonView: UIView, buttonTitle: UILabel, buttonImageView: UIImageView?) {

translatesAutoresizingMaskIntoConstraints = false

// buttonView
addSubview(buttonView)
buttonView.translatesAutoresizingMaskIntoConstraints = false
buttonView.constrainTopToView(view: self)
_ = buttonView.constrainTopToView(view: self)
_ = buttonView.constrainBottomToView(view: self)

_ = buttonView.addHeightConstraint(
constant: MobileContentButtonView.buttonHeight,
constant: minimumButtonHeight,
relatedBy: .greaterThanOrEqual,
priority: 1000
)

buttonView.constrainCenterHorizontallyInView(view: self)

let buttonViewWidth: CGFloat

switch viewModel.buttonWidth {
case .percentageOfContainer(let widthPercentageOfContainer):
buttonViewWidth = containerWidth * widthPercentageOfContainer
case .points(let widthPoints):
buttonViewWidth = widthPoints
}
let buttonViewWidth: CGFloat = getButtonViewWidth()

buttonViewWidthConstraint = buttonView.addWidthConstraint(constant: buttonViewWidth)

// buttonTitle
buttonTitle.isUserInteractionEnabled = false
buttonTitle.backgroundColor = .clear
buttonTitle.numberOfLines = 0
buttonTitle.lineBreakMode = .byWordWrapping
buttonTitle.textAlignment = .center
buttonTitle.font = viewModel.font
buttonTitle.text = viewModel.title
buttonTitle.textColor = viewModel.titleColor

buttonView.addSubview(buttonTitle)
buttonTitle.translatesAutoresizingMaskIntoConstraints = false
buttonTitle.constrainTopToView(view: self)
_ = buttonTitle.constrainBottomToView(view: self)

if buttonIcon == nil {
buttonTitle.constrainLeadingToView(view: self)
buttonTitle.constrainTrailingToView(view: self)
}
else {
buttonTitle.constrainCenterHorizontallyInView(view: self)
}
_ = buttonTitle.constrainTopToView(view: buttonView, constant: buttonTopAndBottomPaddingToTitle)
_ = buttonTitle.constrainBottomToView(view: buttonView, constant: buttonTopAndBottomPaddingToTitle)

// buttonImageView
if let buttonIcon = buttonIcon {

let buttonImageView: UIImageView = UIImageView(image: buttonIcon.image)
buttonImageView.isUserInteractionEnabled = false
buttonImageView.backgroundColor = .clear
if let buttonImageView = buttonImageView, let buttonIcon = viewModel.icon, let buttonIconSize = getButtonIconSize(), let buttonTitleWidth = getButtonTitleWidth() {

buttonTitle.constrainCenterHorizontallyInView(view: buttonView)
buttonTitleWidthForIconConstraint = buttonTitle.addWidthConstraint(constant: buttonTitleWidth)

buttonView.addSubview(buttonImageView)
buttonImageView.translatesAutoresizingMaskIntoConstraints = false
buttonImageView.constrainCenterVerticallyInView(view: self)

_ = buttonImageView.addWidthConstraint(constant: buttonIconSize.width)
_ = buttonImageView.addHeightConstraint(constant: buttonIconSize.height)

switch buttonIcon.gravity {

case .start:
Expand All @@ -124,10 +131,10 @@ class MobileContentButtonView: MobileContentView {
toItem: buttonTitle,
attribute: .leading,
multiplier: 1,
constant: buttonImagePaddingToButtonTitle * -1
constant: 0
)

addConstraint(trailing)
buttonView.addConstraint(trailing)

case .end:

Expand All @@ -138,10 +145,10 @@ class MobileContentButtonView: MobileContentView {
toItem: buttonTitle,
attribute: .trailing,
multiplier: 1,
constant: buttonImagePaddingToButtonTitle
constant: 0
)

addConstraint(leading)
buttonView.addConstraint(leading)

default:

Expand All @@ -152,19 +159,69 @@ class MobileContentButtonView: MobileContentView {
toItem: buttonTitle,
attribute: .leading,
multiplier: 1,
constant: buttonImagePaddingToButtonTitle * -1
constant: 0
)

addConstraint(trailing)
buttonView.addConstraint(trailing)
}
}
else {

_ = buttonImageView.addWidthConstraint(constant: CGFloat(buttonIcon.size))
_ = buttonImageView.addHeightConstraint(constant: CGFloat(buttonIcon.size))

self.buttonImageView = buttonImageView
_ = buttonTitle.constrainLeadingToView(view: buttonView)
_ = buttonTitle.constrainTrailingToView(view: buttonView)
}
}

private func getButtonViewWidth() -> CGFloat {

let buttonViewWidth: CGFloat

switch viewModel.buttonWidth {

case .percentageOfContainer(let widthPercentageOfContainer):
buttonViewWidth = containerWidth * widthPercentageOfContainer

case .points(let widthPoints):
buttonViewWidth = widthPoints
}

return buttonViewWidth
}

private func getButtonTitleWidth() -> CGFloat? {

guard let buttonTitleSizeToFitSize = self.buttonTitleSizeToFitSize, let buttonIconSize = getButtonIconSize() else {
return nil
}

let buttonViewWidth: CGFloat = getButtonViewWidth()

let minSuggestedButtonTitleWidth: CGFloat = buttonViewWidth / 4
var suggestedButtonTitleWidth: CGFloat = buttonViewWidth - (buttonIconSize.width * 2) - (buttonImagePaddingToButtonTitle * 4)

if suggestedButtonTitleWidth < minSuggestedButtonTitleWidth {
suggestedButtonTitleWidth = minSuggestedButtonTitleWidth
}

if buttonTitleSizeToFitSize.width > suggestedButtonTitleWidth {
return suggestedButtonTitleWidth
}

return buttonTitleSizeToFitSize.width + (buttonImagePaddingToButtonTitle * 2)
}

private func getButtonIconSize() -> CGSize? {

guard let buttonIcon = viewModel.icon else {
return nil
}

let buttonIconWidth: CGFloat = CGFloat(buttonIcon.size)
let buttonIconHeight: CGFloat = CGFloat(buttonIcon.size)

return CGSize(width: buttonIconWidth, height: buttonIconHeight)
}

private func setupBinding() {

viewModel.visibilityState.addObserver(self) { [weak self] (visibilityState: MobileContentViewVisibilityState) in
Expand All @@ -177,14 +234,15 @@ class MobileContentButtonView: MobileContentView {
}

private func layoutButtonViewWidthIfNeeded() {

switch viewModel.buttonWidth {
case .percentageOfContainer(let value):
buttonViewWidthConstraint?.constant = containerWidth * value
layoutIfNeeded()
case .points( _):
break

buttonViewWidthConstraint?.constant = getButtonViewWidth()

if let buttonTitleWidth = getButtonTitleWidth() {

buttonTitleWidthForIconConstraint?.constant = buttonTitleWidth
}

layoutIfNeeded()
}

// MARK: - MobileContentView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class MobileContentFlowRow: MobileContentView {

flowItem.translatesAutoresizingMaskIntoConstraints = false

flowItem.constrainTopToView(view: self)
_ = flowItem.constrainTopToView(view: self)
_ = flowItem.constrainBottomToView(view: self)
flowItem.setWidthConstraint(constant: flowItemWidth)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ extension UIView {

func constrainEdgesToView(view: UIView, edgeInsets: UIEdgeInsets = .zero, horizontalConstraintType: UIViewHorizontalContraintType = .leadingAndTrailing) {

constrainTopToView(view: view, constant: edgeInsets.top)
_ = constrainTopToView(view: view, constant: edgeInsets.top)
_ = constrainBottomToView(view: view, constant: edgeInsets.bottom)

switch horizontalConstraintType {
case .leadingAndTrailing:
constrainLeadingToView(view: view, constant: edgeInsets.left)
constrainTrailingToView(view: view, constant: edgeInsets.right)
_ = constrainLeadingToView(view: view, constant: edgeInsets.left)
_ = constrainTrailingToView(view: view, constant: edgeInsets.right)
case .leftAndRight:
constrainLeftToView(view: view, constant: edgeInsets.left)
constrainRightToView(view: view, constant: edgeInsets.right)
}
}

func constrainTopToView(view: UIView, constant: CGFloat = 0) {
func constrainTopToView(view: UIView, constant: CGFloat = 0) -> NSLayoutConstraint {

let top: NSLayoutConstraint = NSLayoutConstraint(
item: self,
Expand All @@ -38,6 +38,8 @@ extension UIView {
)

view.addConstraint(top)

return top
}

func constrainBottomToView(view: UIView, constant: CGFloat = 0) -> NSLayoutConstraint {
Expand Down Expand Up @@ -87,7 +89,7 @@ extension UIView {
view.addConstraint(right)
}

func constrainLeadingToView(view: UIView, constant: CGFloat = 0) {
func constrainLeadingToView(view: UIView, constant: CGFloat = 0) -> NSLayoutConstraint {

let leading: NSLayoutConstraint = NSLayoutConstraint(
item: self,
Expand All @@ -100,9 +102,11 @@ extension UIView {
)

view.addConstraint(leading)

return leading
}

func constrainTrailingToView(view: UIView, constant: CGFloat = 0) {
func constrainTrailingToView(view: UIView, constant: CGFloat = 0) -> NSLayoutConstraint {

let trailing: NSLayoutConstraint = NSLayoutConstraint(
item: self,
Expand All @@ -115,6 +119,8 @@ extension UIView {
)

view.addConstraint(trailing)

return trailing
}

func constrainCenterHorizontallyInView(view: UIView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PageNavigationCollectionView: UIView, NibBased {
}

private let layoutType: PageNavigationCollectionViewLayoutType
private let loggingEnabled: Bool = true
private let loggingEnabled: Bool = false

private var layout: UICollectionViewFlowLayout = PageNavigationCollectionView.getDefaultFlowLayout()
private var currentPageNavigation: PageNavigationCollectionView.CurrentNavigation?
Expand Down

0 comments on commit b46a9e3

Please sign in to comment.