UIActionController replaced UIActionSheet in iOS 8. Is there any way to recreate the showFromToolbar behavior of UIActionSheet in UIActionController? This is the effect I am seeking. Please note though that I am trying to draw a UIActionController coming out of an external action bar button on an iPhone, so I couldn't do this using generic UIActionSheet example too I suppose.
I created a UIBarButtonItem and, in its IBAction I am creating a UIActionController. I tried the following:
var alert = UIAlertController(title: "XYZ", message: "XYZ", preferredStyle: .Alert
// Then created a bunch of UIAlertAction items and added them to alert
var popover = alert.popoverPresentationController
if popover != nil {
var s = sender as UIBarButtonItem
popover?.sourceView = s.customView
popover?.sourceRect = s.customView!.bounds
popover?.permittedArrowDirections = .Any
} else {
println("POPOVER is nil")
}
self.presentViewController(alert, animated: true, completion: nil)
However, this doesn't work with either iPhone or iPad simulators - the alert is showing in middle of screen and the above code always prints "POPOVER is nil". Even if it would have worked in iPad it wouldn't have solved my original problem. Your advice is appreciated.
Found this wonderful tutorial that explains how to do it.
Related
I'm trying to create a UIBarButtonItem that opens the camera once the button has been tapped. For some reason, my takePicture(_sender:) function doesn't seem to be getting called.
I originally tried to create my UIBarButtonItem using the Interface Builder. Here was the interface and a screenshot of the actions connected to the UIBarButtonItem:
And here is the code for my takePicture(_sender:) function:
#IBAction func takePicture(_ sender: UIBarButtonItem) {
print("Taking picture...")
let imagePicker = UIImagePickerController()
// If the device has a camera, take a picture; otherwise,
// just pick from photo library
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
} else {
imagePicker.sourceType = .photoLibrary
}
imagePicker.delegate = self
// Place image picker on the screen
present(imagePicker, animated: true, completion: nil)
}
The little circle next to my function declaration is filled in and connected properly:
However, when I load the simulator and press the button, the UIImagePickerController never appears and my print() function is never called in the code.
So, I then tried to declare the UIBarButtonItem programmatically to see if perhaps it was an issue under-the-hood of Xcode's Interface Builder. Here was my code:
(Note: I deleted the UIBarButtonItem from the Interface Builder and then I connected the UIToolbar to my code using an #IBOutlet.)
override func viewDidLoad() {
super.viewDidLoad()
let takePictureBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.camera, target: self, action: #selector(DetailViewController.takePicture))
toolBar.setItems([takePictureBarButton], animated: false)
}
#objc func takePicture() {
print("Taking picture...")
let imagePicker = UIImagePickerController()
// If the device has a camera, take a picture; otherwise,
// just pick from photo library
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
} else {
imagePicker.sourceType = .photoLibrary
}
imagePicker.delegate = self
// Place image picker on the screen
present(imagePicker, animated: true, completion: nil)
}
As a last ditch attempt at debugging this program and trying to find where the problem lies, I created a temporary button in my UI and connected that to my takePicture(_sender:) function instead (I changed the signature from a UIBarButtonItem to a UIButton). That worked perfectly. This tells me that the problem is not with the function itself, but has something to do with the connection.
I was seconds away from posting this question when I found a similar question. The user stated that the root of their problem lied in a UITapGestureRecognizer on their View Controller.
To solve my problem, I simply set my UITapGestureRecognizer's target to be my StackView instead of the the entire view.
Original:
Resolved:
I'd be curious to learn why the UITapGestureRecognizer stopped my UIBarButtonItem from being tapped, but not the normal UIButton. Seems a little strange...
Swift 4
I went through this problem and referenced above answers. The project I worked on had UIButton as navigation bar item and hence it comes under navigation item and I found out that the outlet for the IBAction should be connected to the button in the bar button item rather than connecting it to the bar button item itself. In mattkx4's question, the IBAction has 'UIBarButtonItem' as its sender. I fixed the issue by connecting the button inside the bar button item to the action.
As you can see there is a button inside the bar button item. Connect the action to this button and the action will be triggered.
make sure you connect your camera button with action for touchUpInside event
First I want to say I didn't find any good answer about it in Swift. I created search bar. On button click it shows and on cancel it hides the searchbar. It is working properly, cancel button is visible on all iPhones but for some reason not on iPad. What should cause this?
That is how I create the searchbar:
//Create searchbar
func createSearchBar(){
searchBar.showsCancelButton = true
searchBar.tintColor = UIColor(red:0.184, green:0.996, blue:0.855, alpha:1.00)
searchBar.placeholder = "Search brands"
searchBar.delegate = self
searchBar.hidden = false
searchBar.alpha = 0
navigationItem.titleView = searchBar
navigationItem.setLeftBarButtonItem(menuButton, animated: true)
navigationItem.setRightBarButtonItem(searchButtton, animated: true)
UIView.animateWithDuration(0.5, animations: {
self.searchBar.alpha = 1
}, completion: { finished in
self.searchBar.becomeFirstResponder()
})
}
Faced the same one of my project. I've posted on apple forum and lot of developers commented as a xcode bug. So I added the cancel button manually for ipad views
func configureCancelBarButton() {
let cancelButton = UIBarButtonItem()
cancelButton.image = UIImage(named: "cancelButton")
cancelButton.action = #selector(viewController.ipadCancelButton(_:))
cancelButton.target = self
self.navigationItem.setRightBarButtonItem(cancelButton, animated: true)
}
And I previously posted an answer about this question. Check that too. :)
https://developer.apple.com/documentation/uikit/uisearchbar/1624283-showscancelbutton
The value of this property is ignored, and no cancel button is displayed, for apps running on iPad.
Apple add that in documents!
The UISearchbar's cancel button will work in iPads if you are NOT using the UISearchbar as NavigationBarItem.
In my iOS app I have a UIViewController ViewController that presents a view that is partly made up of a TableView. The UITableViewCells include a UISegmentControl. When the UISegmentControl's valueHasChanged action is called, I want to present a pop-up. This is the code called within the action:
//Check that the text field isn't empty:
if self.TextField.text == "" {
self.Status.selectedSegmentIndex = 0
let viewController = ViewController()
viewController.alertStatusChangedForEmptyTextField(self)
}
This is the pop-up I have created within the ViewController class that checks if an adjacent text field in the same UITableViewCell is empty or not:
//Alert function that handles when toggle is set even though there is no content.
func alertStatusChangedForEmptyTextField(sender: AnyObject) {
let alert = UIAlertController(title: "Text field has no contents", message: "Please enter a text.", preferredStyle: UIAlertControllerStyle.Alert);
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Cancel, handler: nil));
showViewController(alert, sender: self);
}
I get an error that pops up in the viewDidLoad function of the ViewController, but originates from the showViewController method call within this function (I know because I've tried commenting out only this last line and then everything works fine).
How can I call a pop-up(ViewController) from within a UITableViewCell? Happy to hear suggestions that involve completely different approaches (Creating a custom UITableView subclass? A function that is defined within the TableViewCell class?)
Also, I don't have a root view controller.
check the value of storyboard, there is a good chance that you will find it nil;
storyboard.instantiateViewControllerWithIdentifier("PopMenuViewController") as! PopMenuViewController
I am trying to figure out how to present the pop up from custom tableview cell element. If you figured it out than do share the method :)
I am trying to customize buttons of UIAlertView but however I am unable to achieve it, I am new to swift and I don't how to achieve.
Thank you so much.
Simple answer is no you can not customise default alertViewController buttons but you can achieve it by using custom alertView.
HERE is some available libraries you can use.
To followup on #Dharmesh Kheni's answer, while you get no additional functionality for UIAlertViewController in swift, you can still use libraries in your swift code.
I work for Urban Outfitters and we have an open source customizable alert, URBNAlert
Here is some code, using URBNAlert in swift
let alert = URBNAlertViewController(title: "My Title", message: "Message")
alert.alertStyler.backgroundColor = UIColor.lightGrayColor()
alert.alertStyler.buttonHeight = 44
alert.alertStyler.buttonTitleColor = UIColor.redColor()
alert.alertStyler.cancelButtonBackgroundColor = UIColor.greenColor()
// many, many more things you can customize.
alert.addAction(URBNAlertAction(title: "Button Title", actionType: .Normal, actionCompleted: { (action) -> Void in
// do some stuff here when the user selects this button
}))
alert.show()
Thanks to a kind stackoverflow member I now have AirPrint(ing) working perfectly from the iPhone, but the function call for the iPad is giving me fits. Here is what I have:
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
pic.presentFromRect(self.view.frame, inView:self.view, animated:true, completionHandler: nil)
} else {
pic.presentAnimated(true, completionHandler: nil)
}
The line that calls the print dialog for the iPad is my Swift conversion of Objective-C code that I found numerous times through my Google searching on the topic. It runs and gets called correctly, but all it does is appear to "dim" the iPad screen on the simulator (like something is opening, but it's just a huge grey transparent rectangle that covers the entire screen). If I click anywhere on the dimmed screen it returns to normal and the program continues as if I never pressed my "Print" button (I am using my own "Print" button I created in the Storyboard). I can only test this on the simulator currently, so it could even be a beta bug for all I know... but I'm guessing I'm doing something wrong.
Any suggestions are appreciated!
Thanks.
Thanks to Aaron, my printer select pop-up for the iPad now works on every button in my program except the print button! :) Here is the relevant code:
#IBOutlet var myButton1: BorderedButton!
#IBOutlet var myButton2: BorderedButton!
#IBOutlet var myButton3: BorderedButton!
Works perfectly on all but button 3, which of course is my "Print" button. Here is the function for button 3:
#IBAction func button3Tapped() {
var pic:UIPrintInteractionController = .sharedPrintController()
var viewpf:UIViewPrintFormatter = myTextView.viewPrintFormatter()
pic.delegate = self
pic.showsPageRange = true
pic.printFormatter = viewpf
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
pic.presentFromRect(self.myButton3.frame, inView:self.view, animated:true, completionHandler: nil)
} else {
pic.presentAnimated(true, completionHandler: nil)
}
}
Change that "self.myButton3.frame" to myButton1 or myButton2 and I get the printer select pop-up in the iPad simulator with no problems. But making it myButton3 just gives me the error "fatal error: unexpectedly found nil while unwrapping an Optional value". I'm willing to let it appear on one of the other buttons if I have no other choice, but it would probably be good for me to understand what in the heck is happening!
Thanks again!
Either your outlet for myButton3 isn't connected to your button (try reconnecting it) or it's getting set to nil later, in which case it should be declared as optional: #IBOutlet var myButton3: BorderedButton?.