New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible to add alignment on button styles? #191
Comments
Hey @jhochenbaum, the dialog buttons are subclasses of UIButton, so you can set alignment the same way you would do it with UIButtons. That is
Full width, however, is the default at the moment. That would be a great idea for a Pull Request, though ;) What do you think? |
Thanks for the reply @mwfire Indeed I had tried to do something similar for a while tonight, but with two buttons next to each other, it was really difficult to find good values for each button's contentEdgeInsets where they were positioned correctly and their clickable regions made sense. For some reason I just couldn't get it right, I think because even when moving them around. they try to fill the whole width. Maybe I was setting contentEdgeInsets incorrectly though... The best solution I came up with (without digging into the library itself) is a total hack, but functionality worked nice. This was to add a third invisible dummy button to the left, and set The real solution I guess would indeed be to do this inside the library and change the layout constraint I guess so that it wouldn't be forced to try and auto-fill the entire width, or somehow figure out how to get contentEdgeInsets set correctly on the two buttons! |
@jhochenbaum I have this need, too. Do you already have a good solution? |
@mwfire I'll do it your way. But the effect is not ideal. |
@ETmanwenhan Yes that is what I ran into as well. I ended up hacking it with a third invisible and non-interactive button as mentioned, but a modification to the library that removed or parameterized the auto full-width layout would be a better long-term solution. |
@jhochenbaum // The container stack view for buttons
internal lazy var buttonStackView: UIStackView = {
let buttonStackView = UIStackView()
buttonStackView.translatesAutoresizingMaskIntoConstraints = false
buttonStackView.distribution = **.fillProportionally**
buttonStackView.spacing = 0
return buttonStackView
}() buttonOne.contentHorizontalAlignment = .right
buttonOne.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
buttonTwo.contentHorizontalAlignment = .right
buttonTwo.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10) |
` // Create buttons
|
Again not my preferred route but in the interest of time I moved on for now ;) |
Looks like you're on to the proper solution though! |
@jhochenbaum |
@jhochenbaum Here's my solution: let customVC = NickAlertView()
let alertView = YYPopupDialog(viewController: customVC, title: "标题", msg: "内容", transitionStyle: .zoomIn, completion: nil)
let buttonOne = YYCancelButton(title: "Cancel") {
Loger.log(msg: "canceled")
}
let buttonTwo = YYDefaultButton(title: "Ok") {
Loger.log(msg: "ok:\(customVC.textField.text ?? "")")
}
alertView.addButtons([buttonOne, buttonTwo])
self.present(alertView, animated: true, completion: nil) //
// BaseAlertView.swift
// yiyue
//
// Created by ChenWenHan on 2017/12/19.
// Copyright © 2017年 YiBan. All rights reserved.
//
import UIKit
class YYPopupDialog: UIViewController {
/// First init flag
fileprivate var initialized = false
/// The custom transition presentation manager
fileprivate var presentationManager: PresentationManager!
/// Interactor class for pan gesture dismissal
fileprivate lazy var interactor = InteractiveTransition()
/// Width for iPad displays
fileprivate let preferredWidth: CGFloat
/// The completion handler
fileprivate var completion: (() -> Void)?
/// The content view of the popup dialog
public var viewController: UIViewController
weak var popupContainerView: UIView!
/// The set of buttons
fileprivate var buttons = [PopupDialogButton]()
// MARK: - View life cycle
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard !initialized else { return }
appendButtons()
setupLayout()
initialized = true
}
public init(
viewController: UIViewController,
title: String?,
msg: String?,
transitionStyle: PopupDialogTransitionStyle = .zoomIn,
preferredWidth: CGFloat = 330,
gestureDismissal: Bool = true,
completion: (() -> Void)? = nil) {
self.completion = completion
self.viewController = viewController
self.preferredWidth = preferredWidth
super.init(nibName: nil, bundle: nil)
// Init the presentation manager
presentationManager = PresentationManager(transitionStyle: transitionStyle, interactor: interactor)
// Assign the interactor view controller
interactor.viewController = self
// Define presentation styles
transitioningDelegate = presentationManager
modalPresentationStyle = .custom
// StatusBar setup
//modalPresentationCapturesStatusBarAppearance = true
// Add our custom view to the container
addChildViewController(viewController)
view.addSubview(viewController.view)
viewController.didMove(toParentViewController: self)
popupContainerView = self.viewController.view
// Allow for dialog dismissal on background tap and dialog pan gesture
if gestureDismissal {
let panRecognizer = UIPanGestureRecognizer(target: interactor, action: #selector(InteractiveTransition.handlePan))
popupContainerView.addGestureRecognizer(panRecognizer)
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tapRecognizer.cancelsTouchesInView = false
panRecognizer.cancelsTouchesInView = false
view.addGestureRecognizer(tapRecognizer)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupLayout() {
popupContainerView.snp.updateConstraints({ (make) in
make.centerX.equalTo(self.view.snp.centerX)
make.centerY.equalTo(self.view.snp.centerY)
})
var suffixBtn: UIButton? = nil
for (index, button) in buttons.enumerated().reversed() {
button.contentHorizontalAlignment = .right
button.titleLabel?.adjustsFontSizeToFitWidth = true //自动调整文字宽度
if (index == 0) {
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 0)
} else {
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
}
button.snp.makeConstraints { (make) in
if let btn = suffixBtn {
make.right.equalTo(btn.snp.left)
} else {
make.right.equalTo(popupContainerView.snp.right).offset(-24)
}
make.height.equalTo(30)
make.bottom.equalTo(popupContainerView.snp.bottom).offset(-12)
}
suffixBtn = button
}
}
// MARK: - Dismissal related
@objc fileprivate func handleTap(_ sender: UITapGestureRecognizer) {
// Make sure it's not a tap on the dialog but the background
let point = sender.location(in: popupContainerView)
guard !popupContainerView.point(inside: point, with: nil) else { return }
dismiss()
}
/*!
Dismisses the popup dialog
*/
public func dismiss(_ completion: (() -> Void)? = nil) {
self.dismiss(animated: true) {
completion?()
}
}
deinit {
completion?()
completion = nil
Loger.log(msg: "销毁")
}
// MARK: - Button 相关
/*!
Appends the buttons added to the popup dialog
to the placeholder stack view
*/
fileprivate func appendButtons() {
for (_, button) in buttons.enumerated() {
//button.needsLeftSeparator = index > 0
button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
popupContainerView.addSubview(button)
}
}
/*!
Adds a single PopupDialogButton to the Popup dialog
- parameter button: A PopupDialogButton instance
*/
public func addButton(_ button: PopupDialogButton) {
buttons.append(button)
}
/*!
Adds an array of PopupDialogButtons to the Popup dialog
- parameter buttons: A list of PopupDialogButton instances
*/
public func addButtons(_ buttons: [PopupDialogButton]) {
self.buttons += buttons
}
/// Calls the action closure of the button instance tapped
@objc fileprivate func buttonTapped(_ button: PopupDialogButton) {
if button.dismissOnTap {
dismiss({ button.buttonAction?() })
} else {
button.buttonAction?()
}
}
/*!
Simulates a button tap for the given index
Makes testing a breeze
- parameter index: The index of the button to tap
*/
public func tapButtonWithIndex(_ index: Int) {
let button = buttons[index]
button.buttonAction?()
}
} //
// NickAlertView.swift
// yiyue
//
// Created by ChenWenHan on 2017/12/20.
// Copyright © 2017年 YiBan. All rights reserved.
//
import UIKit
class NickAlertView: UIViewController {
lazy var popupContainerView: UIView = {
let view = UIView(frame: kScreen)
view.clipsToBounds = true
view.layer.cornerRadius = 4
view.backgroundColor = UIColor.white
return view
}()
lazy var titleLable : UILabel = {
let label = UILabel()
label.text = "输入昵称"
label.textColor = UIColor.black
label.font = UIFont.boldSystemFont(ofSize: 16)
return label
}()
lazy var textField: UITextField = {
var textField = UITextField()
textField.placeholder = "8个字以内"
textField.clearButtonMode = .always
textField.font = UIFont.boldSystemFont(ofSize: 14)
return textField
}()
lazy var separator: UIView = {
var view = UIView()
view.backgroundColor = ColorGray5
return view
}()
// MARK: - View life cycle
override func viewDidLayoutSubviews() {
self.setupLayout()
super.viewDidLayoutSubviews()
}
override func loadView() {
super.loadView()
view = popupContainerView
}
override func viewDidLoad() {
super.viewDidLoad()
//view.addSubview(popupContainerView)
popupContainerView.addSubview(titleLable)
popupContainerView.addSubview(textField)
popupContainerView.addSubview(separator)
}
func setupLayout() {
popupContainerView.snp.makeConstraints { (make) in
make.width.equalTo(330)
make.height.equalTo(182)
make.centerX.equalTo(self.view.snp.centerX)
make.centerY.equalTo(self.view.snp.centerY)
}
titleLable.snp.makeConstraints { (make) in
make.top.equalTo(28)
make.left.equalTo(popupContainerView.snp.left).offset(24)
}
textField.snp.makeConstraints { (make) in
make.top.equalTo(titleLable.snp.bottom).offset(32)
make.left.equalTo(popupContainerView.snp.left).offset(24)
make.right.equalTo(popupContainerView.snp.right).offset(-24)
make.height.equalTo(30);
}
separator.snp.makeConstraints { (make) in
make.left.equalTo(textField.snp.left)
make.right.equalTo(textField.snp.right)
make.height.equalTo(0.5);
make.bottom.equalTo(textField.snp.bottom);
}
}
deinit {
Loger.log(msg: "销毁")
}
} |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Report
Environment
Please provide information on your development environment, so we can build with the same scenario.
Dependency management
If you are not using any dependency managers, you can remove this section.
What did you do?
I tried fiddling with
button.contentHorizontalAlignment
andbutton.contentEdgeInserts
in order to make the buttons right aligned, similar to how Google Material aligns "flat buttons" in Material alerts and dialogues:What did you expect to happen?
Buttons to align to the right of the view
What happened instead?
Buttons are always centered and take over the full width of the view, presumably because there is some auto-layout config going on.
Thoughts? Love this library for its ease of use, and ability to add images, but would be really nice if it was just a little more flexible in this way.
The text was updated successfully, but these errors were encountered: