I'm trying to create a profilePic in a Sign Up View Controller. The profilePic is of type UIImageView. I want to be able to tap it so it instantly pulls up a photo library in an ActionSheet Style. And to also have one of the image box a button to access the camera. Is this possible?
import UIKit
class SignUpViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var profilePic: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// PROFILE PICTURE
let tapGesture = UITapGestureRecognizer(target: self, action: "imageTapped:")
profilePic.addGestureRecognizer(tapGesture)
profilePic.userInteractionEnabled = true
}
func imageTapped(gesture:UIGestureRecognizer) {
if let profile1Pic = gesture.view as? UIImageView {
print("Image Tapped")
}
}
Try this code below :
import UIKit
class SignUpViewController: UIViewController, UIImagePickerControllerDelegate {
#IBOutlet weak var profilePic: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: "imageTapped:")
profilePic.addGestureRecognizer(tapGesture)
profilePic.userInteractionEnabled = true
}
func imageTapped(gesture:UIGestureRecognizer) {
if let profile1Pic = gesture.view as? UIImageView {
print("Image Tapped")
showActionSheet()
}
}
func camera()
{
var myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.sourceType = UIImagePickerControllerSourceType.Camera
self.presentViewController(myPickerController, animated: true, completion: nil)
}
func photoLibrary()
{
var myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(myPickerController, animated: true, completion: nil)
}
func showActionSheet() {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
self.camera()
}))
actionSheet.addAction(UIAlertAction(title: "Gallery", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
self.photoLibrary()
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
self.presentViewController(actionSheet, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
profilePic.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)
}
}
Its working on my side..hope will do the some for you !
I recently published a GitHub repository to handle this type of Action Sheet.
You can download this class from here : MSActionSheet
and simply write :
EDIT :
● Now supporting iPad
MSActionSheet(viewController: self, sourceView: sender).showFullActionSheet {
sender.setImage($0, for: .normal)
}
MSActionSheet : is the best library for set user's profile picture.
I used this library but it's not supported in iPad so i
customise for some functions for support to iPad and Display with
popOverController.
Below the step of customisation.
Replace function with showFullActionSheet
func showFullActionSheet(on vc : UIViewController, over btn : UIButton,handler : #escaping (_ : UIImage?) -> Void) {
let sheet = create().addLibrary().addFrontCamera().addRearCamera().addCancelButton()
sheet.show(on: vc,over: btn){ (image : UIImage?) in
handler(image)
}
}
Add code before vc.present(MSActionSheet.sheet!, animated: true, completion: nil) in function show
if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
if let presenter = MSActionSheet.sheet?.popoverPresentationController {
presenter.sourceView = btn
presenter.sourceRect = btn.bounds
}
}
Add below code before clientVC?.present(picker, animated: true, completion: nil) in function handler
if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
picker.modalPresentationStyle = .popover
if let presenter = picker.popoverPresentationController {
presenter.sourceView = sourceBtn
presenter.sourceRect = sourceBtn!.bounds
}
}
How to use
let msActionSheet = MSActionSheet.instance
msActionSheet.showFullActionSheet(on: self,over: btn){ (image) in
btn.setImage(image, for: .normal)
}
msActionSheet.tintColor(color: Constants.kColorBluish)
Swift 3x:
class yourClassName:UIActionSheetDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
#IBAction func yourButtonName(_ sender: UIButton) {
let pickerView = UIImagePickerController()
pickerView.delegate = self
pickerView.allowsEditing = true
let actionSheetControllerIOS8: UIAlertController = UIAlertController(title: "Please select", message: nil, preferredStyle: .actionSheet)
let cancelActionButton: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
print("Cancel") //Cancel
}
actionSheetControllerIOS8.addAction(cancelActionButton)
let saveActionButton: UIAlertAction = UIAlertAction(title: "Take Photo", style: .default) { action -> Void in
print("Take Photo") //Will open Camera
if UIImagePickerController.isSourceTypeAvailable(.camera) {
pickerView.sourceType = .camera
self.present(pickerView, animated: true, completion: { _ in })
}
}
actionSheetControllerIOS8.addAction(saveActionButton)
let deleteActionButton: UIAlertAction = UIAlertAction(title: "Camera Roll", style: .default) { action -> Void in
print("Camera Roll") //Will open Gallery
pickerView.sourceType = .photoLibrary
self.present(pickerView, animated: true, completion: { _ in })
}
actionSheetControllerIOS8.addAction(deleteActionButton)
let deleteActionButton2: UIAlertAction = UIAlertAction(title: "Import from Facebook", style: .default) { action -> Void in
print("Import from Facebook")
}
actionSheetControllerIOS8.addAction(deleteActionButton2)
self.present(actionSheetControllerIOS8, animated: true, completion: nil)
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
//print(info)
if let pickedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
//print(pickedImage)
yourImageView.contentMode = .scaleAspectFit
yourImageView.image = pickedImage
}
dismiss(animated: true, completion: nil)
}
}
Related
// In UITableViewCell
// when I tab on screen it says "open image
2017-11-22 13:15:31.023129+0530 chat[1376:265960] Warning: Attempt to present on whose view is not in the window hierarchy!"
func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
let tappedImage = tapGestureRecognizer.view as! UIImageView
print("open image")
let sb = UIStoryboard.init(name: "Main", bundle: nil)
let vc : openimageinfullscreen = sb.instantiateViewController(withIdentifier: "openimageinfullscreen") as! openimageinfullscreen
self.window?.rootViewController?.present(vc, animated: true, completion: nil)
}
You need to get the top presented view controller and then present.
Try this.
func topViewController() -> UIViewController? {
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
return topController
}
return nil
}
func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
let tappedImage = tapGestureRecognizer.view as! UIImageView
print("open image")
let sb = UIStoryboard.init(name: "Main", bundle: nil)
let vc : openimageinfullscreen = sb.instantiateViewController(withIdentifier: "openimageinfullscreen") as! openimageinfullscreen
self.topViewController()?.present(vc, animated: true, completion: nil)
}
On a separate note, You shouldn't use class name starts with small letter. openimageinfullscreen class should be OpenImageInFullscreen
I'm new to coding and would really appreciate some help on this. I've searched everywhere for a fix to my issue, but can't find one that makes sense to me. Here's my code (error location noted). Thanks in advance!
import UIKit
import Firebase
class UserVC: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
#IBOutlet weak var userImagePicker: UIButton!
#IBOutlet weak var completeSignUpBtn: UIButton!
var userUid: String!
var emailField: String!
var passwordField: String!
var imagePicker: UIImagePickerController!
var imageSelected = false
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
userImagePicker.image = image **//error here**
imageSelected = true
}else {
print("image wasn't selected")
}
imagePicker.dismiss(animated: true, completion: nil)
}
#IBAction func completeAccount (_ sender: Any){
Auth.auth().createUser(withEmail: emailField, password: passwordField, completion:
{(user, error) in
if error != nil {
print(error)
}else{
if let user = user {
self.userUid = user.uid
}
}
})
}
#IBAction func selectedImagePicker(_ sender: Any){
present (imagePicker, animated: true, completion: nil)
}
#IBAction func cancel (_ sender: AnyObject){
dismiss (animated: true, completion: nil)
}
}
You cannot directly assign image to UIButton. Button has different method to set images. Here is swift 3 sample code to set button image.
let playButton = UIButton(type: .custom)
playButton.setImage(UIImage(named: "play.png"), for: .normal)
So try this
userImagePicker.setImage(image,for:.normal)
My code:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.image = image
self.imageStatusLabel.text = "There is a picture"
self.imageStatusLabel.textColor = UIColor.blue()
picker.dismiss(animated: true, completion: nil)
}
And this is the error:
Cannot override 'imagePickerController' which has been marked unavailable: APIs deprecated as of iOS 7 and earlier are unavailable in Swift
Well, I've tried to use the newer function:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// But no image in the parameters
}
But then, there is no image in the parameters and I can get the image.
What should I do?
You have to use the info parameter and make a cast to UIImage. Don't forget that you have to put a "Privacy - Photo Library Usage Description" and a "Privacy - Camera Usage Description" in the info.plist file and fill the values with a string explaining the reason for request the access to photo library and camera.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
pictureImageView.contentMode = .scaleToFill
pictureImageView.image = pickedImage
}
picker.dismiss(animated: true, completion: nil)
}
To use imagePickerController in Swift3 you need add a row with key: Privacy - Photo Library Usage Description and value is a string (e.g: "Access to your photos") to Info.plist file and let's try below:
class YourController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let imagePickerButton: UIButton = {
let btn = UIButton(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
btn.setTitle("Choose a Photo", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.backgroundColor = .blue
btn.addTarget(self, action: #selector(handlePickerDidTap), for: .touchUpInside)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(imagePickerButton)
}
func handlePickerDidTap() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("photo is selected")
// do some thing here
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
Hope it help!
You get the image from the passed info dictionary, see the keys in the documentation
You probably want either
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
or
let image = info[UIImagePickerControllerEditedImage] as? UIImage
import UIKit
import Photos
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBAction func selectPhotoLibrary(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.sourceType = .camera
} else{
print("Kamera desteklenmiyor.")
}
present(picker, animated: true, completion:nil)
}
#IBAction func selectPhotoCamera(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
present(picker, animated: true, completion:nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
picker.dismiss(animated: true, completion:nil)
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
guard let imageData = UIImageJPEGRepresentation(image, 0.8) else { return }
self.imageView.image = image
print(imageData)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion:nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Read more for usage detail --> https://medium.com/#yakupad/swift-uiimagepickercontroller-kullanımı-91771ed4c1d6
I am trying to make a small iPad application which features an 'About' page. I have run into an issue when I try to change the class of the about page scene which is displayed modally, as the application crashes when the user tries to access this page. I wish to change its class to "ViewController", which is the same class as my main window (map view), to create actions from buttons on the 'About' page.
Currently I am unable to ctrl+drag to the .Swift file from the About page unless I change its class. Not sure why this is happening :(
The error printed to the console is as follows:
fatal error: unexpectedly found nil while unwrapping an Optional value
0 specialised_fatalErrorMessage(StaticString, StaticString, StaticString, Uint) -> () –
Here is my storyboard with scenes:
Here is the full ViewController.Swift code:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate {
var location: CLLocation!
let locationManager = CLLocationManager()
// Map variables
var searchController:UISearchController!
var annotation:MKAnnotation!
var localSearchRequest:MKLocalSearchRequest!
var localSearch:MKLocalSearch!
var localSearchResponse:MKLocalSearchResponse!
var error:NSError!
var pointAnnotation:MKPointAnnotation!
var pinAnnotationView:MKPinAnnotationView!
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var segmentedControl: UISegmentedControl!
#IBOutlet weak var showSearchBar: UIBarButtonItem!
#IBOutlet weak var addButton: UIBarButtonItem!
#IBOutlet weak var moreStuff: UIBarButtonItem!
#IBAction func addButton(sender: AnyObject) {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: self.mapView.userLocation.coordinate.latitude, longitude: self.mapView.userLocation.coordinate.longitude)
self.mapView.addAnnotation(annotation)
self.locationManager.startUpdatingLocation()
}
#IBAction func showSearchBar(sender: UIBarButtonItem!) {
searchController = UISearchController(searchResultsController: nil)
searchController.hidesNavigationBarDuringPresentation = false
self.searchController.searchBar.delegate = self
presentViewController(searchController, animated: true, completion: nil)
}
#IBAction func moreStuff(sender: AnyObject) {
self.performSegueWithIdentifier("showMoreStuff", sender:self)
}
#IBAction func refresh(sender: AnyObject) {
self.locationManager.startUpdatingLocation()
}
#IBAction func segmentedControl(sender: UISegmentedControl!) {
if sender.selectedSegmentIndex == 0{
mapView.mapType = MKMapType.Standard
}
else if sender.selectedSegmentIndex == 1{
mapView.mapType = MKMapType.Satellite
}
else if sender.selectedSegmentIndex == 2{
mapView.mapType = MKMapType.Hybrid
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// location delegate methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Error code: " + error.localizedDescription)
}
func searchBarSearchButtonClicked(searchBar: UISearchBar){
searchBar.resignFirstResponder()
dismissViewControllerAnimated(true, completion: nil)
if self.mapView.annotations.count != 0{
annotation = self.mapView.annotations[0]
self.mapView.removeAnnotation(annotation)
}
localSearchRequest = MKLocalSearchRequest()
localSearchRequest.naturalLanguageQuery = searchBar.text
localSearch = MKLocalSearch(request: localSearchRequest)
localSearch.startWithCompletionHandler { (localSearchResponse, error) -> Void in
if localSearchResponse == nil{
let alertController = UIAlertController(title: nil, message: "No Such Place", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
return
}
self.pointAnnotation = MKPointAnnotation()
self.pointAnnotation.title = searchBar.text
self.pointAnnotation.coordinate = CLLocationCoordinate2D(latitude: localSearchResponse!.boundingRegion.center.latitude, longitude: localSearchResponse!.boundingRegion.center.longitude)
self.pinAnnotationView = MKPinAnnotationView(annotation: self.pointAnnotation, reuseIdentifier: nil)
self.mapView.centerCoordinate = self.pointAnnotation.coordinate
}
}
}
I am new to Swift so any help is really appreciated. Thanks!
Edit:
This is the error screen presented to me once the app crashes:
I haven't used mapKit but I still try.
Looking at your error your getting a nil crash, which indicates one of your properties is nil yet you try to use it.
Having a quick read through your code it seams you haven't initialised
var localSearchResponse....
Again i don't know the MK API very well so I am not 100 sure what I'm saying is relevant.
Have you checked that all your IBOutlets are properly connected?
On which line do you get the crash when this happens? Do you get the crash before or after changing to the abouts page?
I am new to swift and I have an app which allows the user to get a picture from their camera roll and display it in an imageview. I have found plenty of tutorials on how to add filters, but how do I isolate this to a touch radius, not the entire image?
import UIKit
import AVFoundation
import Social
import MobileCoreServices
import MessageUI
import iAd
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIAlertViewDelegate, UITextFieldDelegate, UITextViewDelegate {
#IBOutlet var imageView: UIImageView!
let picker = UIImagePickerController()
var cameraUI: UIImagePickerController! = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func filter(sender: UIButton) {
let myPicture = imageView.image
let filter = CIFilter(name: "CIPhotoEffectMono")
filter.setValue(CIImage(image: myPicture), forKey: kCIInputImageKey)
let newImage = UIImage(CIImage: filter.outputImage)
imageView.image = newImage
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let myPicture = imageView.image
for obj in touches {
let touch = obj as! UITouch
let location = touch.locationInView(self.view)
}
}
#IBAction func getImageButton(sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)
{
cameraUI = UIImagePickerController()
cameraUI.delegate = self
cameraUI.sourceType = UIImagePickerControllerSourceType.PhotoLibrary;
cameraUI.mediaTypes = [kUTTypeImage]
cameraUI.allowsEditing = false
self.presentViewController(cameraUI, animated: true, completion: nil)
}
else
{
let alertVC = UIAlertController(title: "Error", message: "Cannot open camera roll.", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style:.Default, handler: nil)
alertVC.addAction(okAction)
presentViewController(alertVC, animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
var chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage //2
imageView.contentMode = .ScaleAspectFit //3
imageView.image = chosenImage //4
dismissViewControllerAnimated(true, completion: nil) //5
}
func noCamera(){
let alertVC = UIAlertController(title: "No Camera", message: "Sorry, this device has no camera", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style:.Default, handler: nil)
alertVC.addAction(okAction)
presentViewController(alertVC, animated: true, completion: nil)
}
func savedImageAlert()
{
var alert:UIAlertView = UIAlertView()
alert.title = "Saved!"
alert.message = "Your picture was saved"
alert.delegate = self
alert.addButtonWithTitle("Ok")
alert.show()
}
}