I want to add a UIImagePickerController in a custom frame, so have been following a few posts around adding the UIImagePickerController view as a subview.
A couple of questions:
How would I adjust the frame of this subview?
After adding as a subview, touch seems to be disabled (I can't browse photos or press the cancel button), how would I solve this?
Many thanks in advance!
My Code:
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePicker.delegate = self;
//This is a subview of self.view.
[self.pickerControllerHolderView addSubview:self.imagePicker.view];
// This seems to adjust the size of the view, but squashes the view.
// self.pickerControllerHolderView.transform = CGAffineTransformMakeScale(1, 0.5);
The internals of this class are private and it is not meant to be added as a subview. It is a self contained view controller and navigation controller and will most likely not work how you expect it to. If you need custom UI for picking photos, you should access the ALAssetsLibrary and display the contents yourself.
Related
I was wondering if this was possible.
To have a class which adds new imageViews to the main view and assigns a gesture recogniser to it.
So in my view builder class, I have the following:
UIImageView *headerPlusIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"plusIcon.png"]];
headerPlusIcon.frame = CGRectMake(header.frame.size.width - 2.5*(logoSize - 8), yPosition*1.6, logoSize*0.9, logoSize*0.9);
headerPlusIcon.userInteractionEnabled = YES;
UIGestureRecognizer *headerTapGesture = [[UIGestureRecognizer alloc] initWithTarget:mainView action:#selector(testTapGesture:)];
[headerPlusIcon addGestureRecognizer:headerTapGesture];
The tap gesture method goes like this:
-(void)testTapGesture:(UITapGestureRecognizer *)gesture
{
dispatch_async(dispatch_get_main_queue(), ^{
mainView.backgroundColor = [UIColor redColor];
});
}
mainView is passed into this class via the constructor and is simply the main view.
This is called like this:
mainViewbuilder = [[MainViewBuilder alloc] initWithBaseView:self.view];
[mainViewbuilder buildHeader];
Unfortunately the tap gesture method never gets called... how would this be done properly?
Thanks!
Try UITapGestureRecognizer
Apple Docs on UITapGestureRecognizer
The code you posted never adds your headerPlusIcon to the view hierarchy. You say in your answer to Adam that you got it working, but I don't see how if you don't add the headerPlusIcon to your view controller's content view hierarchy somewhere.
Note that mucking around in a view controller's view hierarchy from outside is not good object-oriented design.
It would be better to have the view controller ask another object for a view (probably through a protocol) and then add that view itself.
I have designed two ViewControllers - VCLarge and VCSmall. VCSmall is freeform.
When I display VCSmall on top of VCLarge - I shows full screen.
So I play tricks and change the formSize in ViewWillAppear - The VCLarge still does show (I see black)
FYI - I do this when the ViewControllers are in a storyboard and have no problem.
IF you want to present your viewcontroller like UIPopover controller like below...
Please see this OpenSource FPPopver.
It is perfect and works fine.
Very easy to implement.
https://github.com/50pixels/FPPopover
YourViewController *controller = [[YourViewController alloc] init];
//our popover
FPPopoverController *popover = [[FPPopoverController alloc] initWithViewController:controller];
[popover presentPopoverFromView:okButton];
That's all.
If you want to get rid off that ARROW tip, you can do that too!
you use [UIView addSubview] to show it on top of VCLarge.
For example, if you're within VCLarge, you would do something like this:
UIView *smallView = [VCSmall alloc] init...
[self.view addSubview:smallView];
You can adjust the size and or position of smallView using appropriate CGRects for smallView.
Editing a photo after it's been taken (moving and scaling it) works fine in my app with this line:
[imagePicker setAllowsEditing:YES];
But if I also use a cameraOverlayView, the editing mode doesn't work anymore. The screen comes up, but pan and pinch gestures don't make anything happen.
I'm using your average image picker controller:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
And I add a camera overlay view, created from a custom view controller's view:
CameraOverlayViewController *overlayController = [[CameraOverlayViewController alloc] init];
UIView *overlayView = overlayController.view;
[imagePicker setCameraOverlayView:overlayView];
In IB, that view is set up to enable user interaction and multiple touch, which allows it to zoom and focus while taking the picture. But once the picture is taken and it enters editing mode, you cannot pan or pinch to move or scale the photo.
What am I missing?
Does your overlay take up the entire space of the camera view? If so, touches are going to the overlay instead of the view below, even if you have a transparent background.
Add this method to your overlay view and it will ignore touches so that they are passed to the views below. (You are overriding a method of UIView that detects touches.)
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
return NO;
}
Note: as well as that fantastic tip, you may also want to use this piece of info, to remove your overlay view, at that stage: UIImagePicker cameraOverlayView appears on Retake screen
I'm currently making a photo decoration app. The *holderView is the sticker that has been chosen by user. Whenever I try to load a photo from photo library or take a photo and then load back to this page, additional *holderView added programmatically, which is the sticker that I've previously chosen before taking a photo, duplicated sticker appears after that, which is not what I want it to be.
How should I write the code for not letting this happen?
Thanks a lot.
- (void)viewWillAppear:(BOOL)animated {
UIView *holderView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, _imagePicker.selectedImage.size.width, _imagePicker.selectedImage.size.height)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:[holderView frame]];
[imageView setImage:_imagePicker.selectedImage];
[holderView addSubview:imageView];
...
}
Your problem seems to be that your using the viewWillAppear method instead of the viewDidLoad. This will cause multiple "imageViews" because your adding a new one every time you hide then show the viewController it's presented in. what you want to do is move the creation of the imageView (if there really is suppose to only be 1) to the viewDidLoad method and make that imageView accessible to the entire class, then in the viewWillApear simply change the image inside the imageView to the newly selected one.
I have a UIPopoverController with two view controllers inside of it. I'm building it like so:
CommentsPopoverController *commentsPopoverController = [[CommentsPopoverController alloc] init];
self.delegate = commentsPopoverController;
commentsPopoverController.navigationItem.title = #"Comments";
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:commentsPopoverController];
popover = [[UIPopoverController alloc] initWithContentViewController:navController];
Inside my commentsPopoverController I have this:
commentsViewController = [[CommentsViewController alloc] init];
commentsViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
addCommentsViewController = [[AddCommentViewController alloc] init];
addCommentsViewController.view.frame = CGRectMake(0, commentsViewController.view.bounds.size.height - 200, 320, 346);
addCommentsViewController.view.backgroundColor = [UIColor darkGrayColor];
[self.view addSubview:addCommentsViewController.view];
[self.view addSubview:commentsViewController.view];
So when I first load the popover, the addCommentsViewController is hidden by the commentsViewController. When I reveal it, it looks like this:
So far so good. The problem I'm having is that from here, when the user rotates the device or shows the keyboard or shows the keyboard THEN rotates the device things start to get out of whack. The top view controller (commentsViewController) which is a UITableView always does the right thing no matter what the orientation is or whether or not the keyboard is showing. But the bottom view controller (addCommentsViewController) doesn't automatically change it's origin.y to stay directly under the top view controller.
So I've basically had to hack the crap out of my code to keep the addCommentsViewController directly under the commentsViewController by constantly calculating the height of the top view controller so that I could adjust the bottom view controller's origin.y. This involved dropping in NSNotifications for the keyboard's show/hide state and for the device's orientation and constantly recalculating. Very hackish and ugly.
So my question (finally) is: Is there an easier way of controlling these views or am I stuck hacking it the way I did?
To handle rotation, there are two appropriate techniques. One is that you make CommentsPopoverController's view a subclass of UIView that overrides layoutSubviews to lay out your two views properly. The other is that you define viewDidLayoutSubviews on CommentsPopoverController to lay out your views. If you lay out your views in either of these methods, you shouldn't have to subscribe to rotation notifications.
As for moving your view out from under the keyboard, that is discussed in the Text, Web, and Editing Programming Guide for iOS. Part of the technique involves subscribing to keyboard will show/did hide notifications.
I assume your CommentsViewController is a subclass of UITableViewController, because UITableViewController takes care of adjusting the table view when the keyboard is hidden or shown.