I created a program where picker shows upon clicking on my text field and I am trying to dismiss it when I click the "done" or "cancel" button on my toolbar.
I have no idea where it went wrong. Although it says
"2017-09-28 20:45:27.877897-0600 project1 [51296:5112470] [LayoutConstraints] Unable to simultaneously satisfy constraints."
All of my constraints are working fine atm..
Here is my code:
#IBOutlet weak var textField1: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let picker: UIPickerView
picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 300))
picker.backgroundColor = .white
picker.showsSelectionIndicator = true
picker.delegate = self
picker.dataSource = self
let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 40))
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action:
Selector(("donePicker")))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: Selector(("donePicker")))
)
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: true)
toolBar.isUserInteractionEnabled = true
let bgView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 250 + toolBar.frame.size.height))
print(picker.frame.size.height, toolBar.frame.size.height, bgView.frame.size.height)
bgView.addSubview(picker)
bgView.addSubview(toolBar)
textField1.inputView = bgView
}
func donePicker() {
textField1.resignFirstResponder()
}
And this is the error that it gives me:
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2017-09-28 20:45:29.253610-0600 project1[51296:5112470] [MC] Lazy loading NSBundle MobileCoreServices.framework
2017-09-28 20:45:29.255001-0600 project1[51296:5112470] [MC] Loaded MobileCoreServices.framework
2017-09-28 20:45:29.274235-0600 project1[51296:5112470] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /Users/Andrew/Library/Developer/CoreSimulator/Devices/EE44EDE5-BDF6-4A15-A44B-387E14685DAA/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
300.0 44.0 294.0
2017-09-28 20:45:30.401748-0600 project1[51296:5112470] [MC] Reading from private effective user settings.
2017-09-28 20:45:31.827410-0600 project1[51296:5112470] -[project1.CalculateViewController donePicker]: unrecognized selector sent to instance 0x7faac1d0fab0
2017-09-28 20:45:31.835746-0600 project1[51296:5112470] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[project1.CalculateViewController donePicker]: unrecognized selector sent to instance 0x7faac1d0fab0'
*** First throw call stack:
(
0 CoreFoundation 0x000000010c8a11cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010a93cf41 objc_exception_throw + 48
2 CoreFoundation 0x000000010c921914 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 UIKit 0x000000010d4660bd -[UIResponder doesNotRecognizeSelector:] + 295
4 CoreFoundation 0x000000010c824178 ___forwarding___ + 1432
5 CoreFoundation 0x000000010c823b58 _CF_forwarding_prep_0 + 120
6 UIKit 0x000000010d23f9bd -[UIApplication sendAction:to:from:forEvent:] + 83
7 UIKit 0x000000010dc3353f __45-[_UIButtonBarTargetAction _invoke:forEvent:]_block_invoke + 154
8 UIKit 0x000000010dc33470 -[_UIButtonBarTargetAction _invoke:forEvent:] + 181
9 UIKit 0x000000010d23f9bd -[UIApplication sendAction:to:from:forEvent:] + 83
10 UIKit 0x000000010d3b6183 -[UIControl sendAction:to:forEvent:] + 67
11 UIKit 0x000000010d3b64a0 -[UIControl _sendActionsForEvents:withEvent:] + 450
12 UIKit 0x000000010d3b53cd -[UIControl touchesEnded:withEvent:] + 618
13 UIKit 0x000000010d2b3d4f -[UIWindow _sendTouchesForEvent:] + 2807
14 UIKit 0x000000010d2b5472 -[UIWindow sendEvent:] + 4124
15 UIKit 0x000000010d25a802 -[UIApplication sendEvent:] + 352
16 UIKit 0x000000010db8ca50 __dispatchPreprocessedEventFromEventQueue + 2809
17 UIKit 0x000000010db8f5b7 __handleEventQueueInternal + 5957
18 CoreFoundation 0x000000010c8442b1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
19 CoreFoundation 0x000000010c8e3d31 __CFRunLoopDoSource0 + 81
20 CoreFoundation 0x000000010c828c19 __CFRunLoopDoSources0 + 185
21 CoreFoundation 0x000000010c8281ff __CFRunLoopRun + 1279
22 CoreFoundation 0x000000010c827a89 CFRunLoopRunSpecific + 409
23 GraphicsServices 0x00000001122ee9c6 GSEventRunModal + 62
24 UIKit 0x000000010d23dd30 UIApplicationMain + 159
25 UofA Engineering Master 0x0000000109ffa307 main + 55
26 libdyld.dylib 0x000000010fbc5d81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I have tried a different approach to show PickerView and toolbar in textField.
Try this if it helps in your scenario:
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(CalculateViewController.donePicker))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(CalculateViewController.cancelPicker))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
textField1.inputView = pickerView
textField1.inputAccessoryView = toolBar
You can see the error message is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[project1.CalculateViewController donePicker]: unrecognized selector sent to instance 0x7faac1d0fab0'
For Swift, we don't define the selector like that (it's Objective C way). You should use like this:
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action:
#selector(donePicker))
since the error is unrecognized selector sent to instance, you may let the picker become a property. replace the let picker: UIPickerView out of the viewdidload method with var picker: UIPickerView?
Related
I have an UIToolbar containing a UITextField. I want to show the toolbar above the keyboard and then display it again when I finish editing inside the textfield.
The issue is that it is working when selecting the textfield. However, the toolbar is disappearing from the view when hiding the keyboard.
What should be done to redisplay it again to my view?
My Swift code is:
Add UITextFieldDelegate
class ATCChatThreadViewController: MessagesViewController, MessagesDataSource, MessageInputBarDelegate, UITextFieldDelegate {
Create ToolBar is as below
func createToolbar(){
//Fixed space
let fixed = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: self, action: nil)
fixed.width = 10
//Camera
//let img = UIImage(named: "camera-filled-icon")!.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
let img = UIImage.localImage("camera-filled-icon", template: true)
let iconSize = CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30))
let iconButton = UIButton(frame: iconSize)
iconButton.setTitleColor(uiConfig.primaryColor, for: .normal)
iconButton.setBackgroundImage(img, for: .normal)
let cameraItem = UIBarButtonItem(customView: iconButton)
cameraItem.tintColor = uiConfig.primaryColor
iconButton.addTarget(self, action: #selector(cameraButtonPressed), for: .touchUpInside)
//TextField true
textFieldChat = UITextField(frame: CGRectMake(0,0,(self.view.frame.size.width - 100) ,30))
textFieldChat.tintColor = uiConfig.primaryColor
textFieldChat.textColor = uiConfig.inputTextViewTextColor
textFieldChat.backgroundColor = uiConfig.inputTextViewBgColor
textFieldChat.layer.cornerRadius = 14.0
textFieldChat.layer.borderWidth = 0.0
textFieldChat.font = UIFont.systemFont(ofSize: 16.0)
textFieldChat.delegate = self
textFieldChat.attributedPlaceholder = NSAttributedString(string: "Start typing...".localized(), attributes: [NSAttributedString.Key.foregroundColor: uiConfig.inputPlaceholderTextColor])
let paddingView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 20))
textFieldChat.leftView = paddingView
textFieldChat.leftViewMode = .always
let textFieldButton = UIBarButtonItem(customView: textFieldChat)
//Fixed space
let fixedTwo = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: self, action: nil)
fixedTwo.width = 10
//Send Button
let imgSend = UIImage.localImage("share-icon", template: true)
let iconSendSize = CGRect(origin: CGPoint.zero, size: CGSize(width: 30, height: 30))
let sendButton = UIButton(frame: iconSendSize)
sendButton.setTitleColor(uiConfig.primaryColor, for: .normal)
sendButton.setBackgroundImage(imgSend, for: .normal)
let sendItem = UIBarButtonItem(customView: sendButton)
sendItem
.tintColor = uiConfig.primaryColor
sendButton.addTarget(self, action: #selector(sendBtnPressedWith), for: .touchUpInside)
//Flexible Space
// let flexible = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil)
let flexible = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: self, action: nil)
flexible.width = 10
//Toolbar
var bottomsafeAreaHeight: CGFloat?
if #available(iOS 11.0, *) {
bottomsafeAreaHeight = UIApplication.shared.windows.first{$0.isKeyWindow }?.safeAreaInsets.bottom ?? 0
} else {
// Fallback on earlier versions
bottomsafeAreaHeight = bottomLayoutGuide.length
bottomsafeAreaHeight = UIApplication.shared.keyWindow?.rootViewController?.bottomLayoutGuide.length ?? 0
}
toolbar = UIToolbar(frame: CGRectMake(0,(self.view.frame.size.height - 116 - (bottomsafeAreaHeight ?? 0)),view.frame.width,50))
toolbar.sizeToFit()
toolbar.barTintColor = UIColor.f5f5f5ColorBg()
toolbar.isTranslucent = false
toolbar.tintColor = uiConfig.primaryColor
toolbar.items = [fixed, cameraItem, fixed, textFieldButton,fixedTwo, sendItem,flexible]
view.addSubview(toolbar)
}
// MARK: - UITextFieldDelegate
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
textFieldChat.inputAccessoryView = toolbar
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
view.addSubview(toolbar)
self.toolbar.isHidden = false
return true
}
if only chat etxfield is using toolbar then replace line:
view.addSubview(toolbar)
with
textFieldChat.inputAccessoryView = toolbar
remove both methods textFieldShouldBeginEditing and textFieldShouldEndEditing
I want to close my uidatepicker and my toolbar by pressing a "done"-button in my toolbar.
I am using a label instead of a textfield so the common solutions don't work.
I have tried:
#IBAction func ButtonPressed(_ sender: UIButton) {
print("hallo")
let picker = UIDatePicker()
picker.backgroundColor = .white
picker.datePickerMode = .date
//picker.sizeToFit()
var datumComponents = DateComponents()
datumComponents.year = 2019
datumComponents.month = 6
datumComponents.day = 1
let meinStartKalender = Calendar.current
let StartDatum = meinStartKalender.date(from: datumComponents)
picker.minimumDate = StartDatum
picker.maximumDate = Date()
let pickerSize1 = myView.bounds.width
picker.addTarget(self, action: #selector(dueDateChanged(sender:)), for: UIControl.Event.valueChanged)
picker.frame = CGRect(x:0.0, y: self.view.frame.height - 300 , width: pickerSize1, height: 200)
self.view.addSubview(picker)
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.backgroundColor = .red
toolBar.frame = CGRect(x:0.0, y: self.view.frame.height - 340 , width: pickerSize1, height: 40)
self.view.addSubview(toolBar)
what I've found already:
add:
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.donePressed(_:)))
toolBar.setItems([doneButton], animated: false)
but the error message says:
Value of type 'ViewController' has no member 'donePressed'
how can I change the action or how can I implement a button that works?
Add this in your code
#objc
func donePressed(_ sender: UIButton) {
}
I'm trying trying to change my toolbar that I added Programmatically. but it didn't reflect. so any help
this is my code. and in the viewController I embed the view from UINavigation Controller
class ViewController: UIViewController,UIToolbarDelegate {
private var toolItems : [UIBarButtonItem] = []
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
navigationController?.isToolbarHidden = false
let height: CGFloat = 130
let bounds = self.navigationController?.toolbar.bounds
navigationController?.toolbar.barTintColor = UIColor(red: 0.0/42, green: 0.0/42, blue: 0.0/56, alpha: 1)
navigationController?.toolbar.tintColor = UIColor.white
navigationController?.toolbar.frame = CGRect(x: 0, y: self.view.frame.height - 80, width: self.view.frame.width, height: (bounds?.height)! + height)
navigationController?.toolbar.isTranslucent = false
navigationController?.toolbar.heightAnchor.constraint(equalToConstant: (bounds?.height)! + height).isActive = true
navigationController?.toolbar.sizeToFit()
let btn_Tracking = UIButton(type: .custom)
btn_Tracking.setImage(UIImage(named: "icon-trackingtabbed#2x"), for: .normal)
btn_Tracking.sizeToFit()
let trackingItem = UIBarButtonItem(customView: btn_Tracking)
///Sign
let btn_sign = UIButton(type: .custom)
btn_sign.setImage(UIImage(named: "icon-trackingtabbed#2x"), for: .normal)
btn_sign.sizeToFit()
let sginItem = UIBarButtonItem(customView: btn_sign)
let fixedSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
fixedSpace.width = 10.0
let flexibleSpace: UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
self.toolbarItems = [flexibleSpace,sginItem,flexibleSpace,trackingItem,flexibleSpace]
}
}
I am trying to add a custom navigation bar to my app, but whenever it loads I get the 'Unable to simultaneously satisfy constraints' error. I can't seem to programatically remove any of the constraints - and I definitely haven't added any.
Console Output:
"<NSLayoutConstraint:0x600000092750 UILabel:0x7ffc40507d20'Configure'.firstBaseline == UILayoutGuide:0x6000007b18e0'TitleView(0x7ffc40503120)'.top + 23 (active)>",
"<NSLayoutConstraint:0x600000092840 UILabel:0x7ffc40507d20'Configure'.top >= UILayoutGuide:0x6000007b18e0'TitleView(0x7ffc40503120)'.top (active)>"
App Delegate:
self.window = UIWindow(frame: UIScreen.main.bounds)
let nav1 = UINavigationController(navigationBarClass: CustomNavBar.self, toolbarClass: nil)
let mainView = TableViewController()
nav1.viewControllers = [mainView]
self.window!.rootViewController = nav1
self.window!.makeKeyAndVisible()
CustomNavBar Class:
self.frame.size.height = 60
self.backgroundColor = appColour
self.tintColor = UIColor.white
self.titleTextAttributes = [
NSForegroundColorAttributeName : UIColor.white,
NSFontAttributeName : UIFont(name: "Avenir-Heavy", size: 30)!
]
self.setTitleVerticalPositionAdjustment(-5, for: .default)
ViewController:
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(start))
navigationItem.rightBarButtonItem!.imageInsets = UIEdgeInsets(top: -7, left: 0, bottom: 0, right: 0)
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "Folder")!, style: .plain, target: self, action: #selector(viewSaved))
navigationItem.leftBarButtonItem!.imageInsets = UIEdgeInsets(top: -7, left: 0, bottom: 0, right: 0)
self.title = "Configure"
I just can't figure out what to do.
Thanks in advance!
The issue is with your font-size in your CustomNavBar Class, reduce the font size until you don't get the constraint error.
self.titleTextAttributes = [
NSForegroundColorAttributeName : UIColor.white,
NSFontAttributeName : UIFont(name: "Avenir-Heavy", size: <30>)!
]
I have used UIPickerView without UITextField. After user tap on button, UIPickerView will display.
Anyway, I have no idea how to dismiss UIPickerView. I have tried to set inputAccessoryView with UIToolbar but the complier said it's get-only property.
My code:
let toolbar = UIToolbar()
toolbar.barStyle = UIBarStyle.default
toolbar.isTranslucent = true
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(RegisterViewController.pickerDoneButton))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: self, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(RegisterViewController.pickerCancelButton))
toolbar.setItems([cancelButton, spaceButton, doneButton], animated: true)
toolbar.isUserInteractionEnabled = true
pickerView.inputAccessoryView = toolbar
Error: Cannot assign to property: 'inputAccessoryView' is a get-only property
Try to add subview to the UIPickerView
It seems like UIPickerView is not letting its children receive touch events. If you want to add toolbar to pickerview without textfield you can create a top level container UIView to hold both toolbar and picker view like this:
let picker = UIView(frame: CGRect(x: 0, y: view.frame.height - 260, width: view.frame.width, height: 260))
// Toolbar
let btnDone = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.monthdoneButtonAction))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelClick))
let barAccessory = UIToolbar(frame: CGRect(x: 0, y: 0, width: picker.frame.width, height: 44))
barAccessory.barStyle = .default
barAccessory.isTranslucent = false
barAccessory.items = [cancelButton, spaceButton, btnDone]
picker.addSubview(barAccessory)
// Month UIPIckerView
monthPicker = UIPickerView(frame: CGRect(x: 0, y: barAccessory.frame.height, width: view.frame.width, height: picker.frame.height-barAccessory.frame.height))
monthPicker.delegate = self
monthPicker.dataSource = self
monthpickerData = ["January","February","March","April","May","June","July","August","September","October","November","December"]
monthPicker.backgroundColor = UIColor.white
picker.addSubview(monthPicker)