I am creating my own UIImagePicker Overlay and am using a Xib in order to display the overlay. Whenever I present the imagepicker, it seems to present twice, once when I call the main bundle to load the nib and the other when I explicitly present the imagepickercontroller. The main problem i'm having is when I dismiss the imagepickercontroller, the first one goes, which is great, but the underlying view of the xib still remains and doesn't go regardless of what i do.
I tried to convert the Objective-C example project for how to create a custom uiimagepickercontroller Apple has on their website into Swift. I'm not sure what I"m doing wrong, here is my code:
func showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType) {
let picker = UIImagePickerController()
picker.modalPresentationStyle = UIModalPresentationStyle.CurrentContext
picker.sourceType = sourceType
picker.delegate = self
if sourceType == UIImagePickerControllerSourceType.Camera {
//gets rid of the out of the box imagepicker
picker.showsCameraControls = false
//loads the overlay xib for the camera
NSBundle.mainBundle().loadNibNamed("OverlayView", owner: self, options: nil)
self.overlayView.frame = (picker.cameraOverlayView?.frame)!
picker.cameraOverlayView = self.overlayView
self.overlayView = nil
//makes the image capture screen the full screen size
let screenSize: CGSize = UIScreen.mainScreen().bounds.size
let cameraAspectRatio: Float = 4.0 / 3.0
let imageWidth:Float = floorf(Float(screenSize.width) * cameraAspectRatio)
let scale: Float = ceilf((Float(screenSize.height + 120) / imageWidth) * 10.0) / 10.0
picker.cameraViewTransform = CGAffineTransformMakeScale(CGFloat(scale), CGFloat(scale))
}
self.imagePickerController = picker
self.presentViewController(self.imagePickerController, animated: true, completion: nil)
}
Here is the code for a button on the xib dismissing the view. How can i fix this? Because i'm printing out the array of view controllers on the navigation stack, and it only shows one.
#IBAction func goBack(sender: AnyObject) {
self.imagePickerController.dismissViewControllerAnimated(true, completion: nil)
}
It sounds like you have your view controller's view outlet connected to the view in your .xib file in addition to the overlayView outlet. This would probably cause what you're describing.
Related
I would like to model a table view after one found in the Todoist app (see below), is it possible to do this without and additional framework? If so how would I go about doing this?
You can create a view controller with a UITableView and present it as UIPopoverPresentationController
let vc = UIViewController()
vc.modalPresentationStyle = .popover
vc.preferredContentSize = CGSize(width: 200, height: 200)
let popUp = vc.popoverPresentationController
popUp?.permittedArrowDirections = .up
popUp?.delegate = self
popUp?.sourceView = sender as! UIView // here set the frame of the button that the arrow points to when popup is shown
present(vc, animated: true, completion: nil)
//
Inside the vc that you presents the popup make it implements the delegate UIPopoverPresentationControllerDelegate and write this method
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
I'm having a problem with the iPhone X simulator in Xcode behaving differently to other simulators.
What I'm trying to do it click on a view which brings up a UIPicker. When a date is selected and the user clicks ok the popover disappears and a label in the view is updated with the string of what was selected. This is working on the 2 physical devices I'm using (iPhone6 plus and iPad). It's also working in simulators for iPhone 5 and 8. However when I try the iPhoneX it doesn't work.
As soon as the user the taps the picker or moves it it fades of the screen and nothing gets updated. As I don't have a physical iPhoneX to test with I don't know if this is just a simulator issue or if it will also happen on an actual device. Is this just a simulator issue? How can I fix this? Will this also happen on an actual device?
Below is the function I'm using to display the custom popover containing the picker view.
/// When the view is tapped it will display user options and then update the label in the view.
///
/// - Parameters:
/// - box: LabelAndWhiteBarView is my own custom UIView for this project.
/// - strings: array of strings to be displayed by the picker
func displayStringPicker(box: LabelAndWhiteBarView, strings: [String]){
// Custom viewcontroller containing a UIPickerView, title UILabel and a cancel and OK UIButton.
let floatingPickerViewController:FloatingPickerViewController = UIStoryboard(name: "FloatingPickerStoryboard", bundle: nil).instantiateInitialViewController()! as! FloatingPickerViewController
floatingPickerViewController.modalPresentationStyle = .popover
floatingPickerViewController.preferredContentSize = defaultPickerSize // set elsewhere so it doesnt cover the whole screen
//Adds a blank string in front of each array so the user can always pick and empty option
var stringsWithBlankFirstOption = strings
stringsWithBlankFirstOption.insert("", at: 0)
floatingPickerViewController.stringArray = stringsWithBlankFirstOption
//tells the picker view which view to update
floatingPickerViewController.senderBox = box
floatingPickerViewController.delegate = self
floatingPickerViewController.view.layer.borderWidth = 1
floatingPickerViewController.view.layer.borderColor = UIColor.clear.cgColor
let popoverMenuViewController = floatingPickerViewController.popoverPresentationController
popoverMenuViewController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue:0) // removed the arrow thats defauls on a popover
popoverMenuViewController?.delegate = self
popoverMenuViewController?.sourceView = self.view
popoverMenuViewController?.sourceRect = CGRect(
x: 0,
y: 0,
width: self.view.frame.width,
height: self.view.frame.height)
floatingPickerViewController.dismissBlock = {
self.dismiss(animated: false, completion: nil)
}
present(
floatingPickerViewController,
animated: false,
completion: nil)
/// set the picker to preselect what was already selected
let indexOfSelectedItem = floatingPickerViewController.stringArray.index(of: box.displayLabel.text ?? "") ?? 0
//pre selects the last selected string
floatingPickerViewController.numberPicker.selectRow(indexOfSelectedItem, inComponent: 0, animated: false)
}
new to app development.
What I want to do is allow the user to take 2 photos from the Camera and review them. Will then code around those two photos. Preference is just to take from Camera but also could be from PhotoLibrary.
My thought process around this was, click a button to take first photo, then display that photo in a UIPageViewController then allow them to take another photo by pushing a Button to call the camera again, then that Photo would be the second as part of the UIPageViewController. So the user can swipe with the 2 dots at the bottom to review, then select confirm.
So what I did was follow the UIImagePickerController to be able to allow the user to select from library or Camera and also implemented the UIPageViewController. But having trouble putting the two together.
When I get an image from Camera I think I need to save it. The pageviewcontroller gets the filenames from a NSMutableArray.
With the viewDidLoad... I call the Camera, and also the pageViewController. My problem is the pageviewcontroller gets data from pageImages[] but how do I populate the array with the image name string? Did I do it correctly below? I think i may have a problem in that does the pageviewcontroller controller automatically update once i dismiss the picker otherwise will never get the image from the camera. I am thinking i may have to call camera then pass the data to the view controller through segues?
Other thought I was having was to have a view controller that just displays the taken image, saves it, adds filename to array, then when user takes another photo, the image is saved and added to array and then passed through segue to the pageviewcontroller for the user to be able to scroll through both and either confirm or delete. Thoughts?
override func viewDidLoad() {
super.viewDidLoad()
createPhoto()
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PhotoPageViewControllerStoryBoard") as! UIPageViewController
self.pageViewController.dataSource = self
var startVc = self.pageViewControllerAtIndex(0) as PhotoContentPageViewController
var viewControllers = NSArray(object: startVc)
self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRectMake(0, -10, self.view.frame.size.width, self.view.frame.size.height-30)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
var newImage: UIImage
if let possibleImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
newImage = possibleImage
} else if let possibleImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
newImage = possibleImage
} else {
return
}
if (picker.sourceType == UIImagePickerControllerSourceType.Camera) {
let imageName = NSUUID().UUIDString
let imagePath = getDocumentsDirectory().stringByAppendingPathComponent(imageName)
if let jpegData = UIImageJPEGRepresentation(newImage, 80) {
jpegData.writeToFile(imagePath, atomically: true)
}
pageImages!.addObject(imageName)
}
dismissViewControllerAnimated(true, completion: nil)
}
ok, think I got it, i changed the array to pass to the pageviewcontroller from the contentviewcontroller UIImages instead of filename strings.
Also, since the array was nil i didn't start the pageviewcontroller until after the first image was taken or chosen.
Off to battle the next set of code, to actually do something with the two image. most likely will need some help in the future... near future. Thanks.
I simply want to present a small option dialog over an existing main UIViewController/UIView , so that on an IPad I would see a small Dialog and in the Background I will see the Main View.
I managed to show a UIViewController/UIView in a modal view style as follow:
func showoptions(){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("Options") as! UIViewController
controller.modalPresentationStyle = UIModalPresentationStyle.Popover
let popoverPresentationController = controller.popoverPresentationController
// result is an optional (but should not be nil if modalPresentationStyle is popover)
if let _popoverPresentationController = popoverPresentationController {
// set the view from which to pop up
_popoverPresentationController.sourceView = self.view;
//_popoverPresentationController.sourceRect = CGRectMake(60, 100, 500, 500)
//_popoverPresentationController. .setPopoverContentSize(CGSizeMake(550, 600), animated: true)
//_popoverPresentationController.sourceView.sizeToFit();
// present (id iPhone it is a modal automatic full screen)
self.presentViewController(controller, animated: true, completion: nil)
}
}
But I have still some issues:
1. Howto get rid of the arrow shown at the border.
2. Howto size this modal view. It is shown to small and I would like to fit it to the largest controls in the UIControllerView/UIView.
any help ?
Try changing _popoverPresentationController.permittedArrowDirections to empty option set
Change controller.preferredContentSize to match your desired size
I needed something similar and ended up presenting a view controller as a modal with a transparent background over the current context. There I made a smaller opaque UIView with what I wanted.
I'm trying to add ViewControllers in UIScrollView and VC's are loaded from xib. This is my code
let onevc = OneViewController()
self.addChildViewController(onevc )
self.scrollView.addSubview(onevc .view)
onevc.didMoveToParentViewController(self)
let twovc = TwoViewController()
var frame:CGRect = twovc.view.frame
frame.origin.x = 320
twovc.view.frame = frame
self.addChildViewController(twovc)
self.scrollView.addSubview(twovc.view)
twovc.didMoveToParentViewController(self)
self.scrollView.contentSize = CGSizeMake(640, self.view.frame.size.height)
self.scrollView.pagingEnabled = true
Both the viewcontrollers are added but they are not visible, scrollview is just showing white screen. I have added few elements in ViewControllers and also to test I added println("something") So when the view is loaded, It is printing something but not showing anything. what am I doing wrong here?
Perhaps you forgot to specify the nib name for the view controller?
let onevc = self.storyboard!.instantiateViewControllerWithIdentifier("OneViewController")
or
let onevc = OneViewController(nibName: "OneViewController", bundle: nil)
Same goes for the 2nd one.