I have an UIImage captured from the camera with UIImagePickerController.
Now after the user clicks on it, I'd like it to show full screen and be able to to zoom it in and out using pinch gestures and also the double tap gesture to zoom in a particular area. In other words, I'd like to emulate what the ios's default image browser does.
I display the captured image in an UIImageView with:
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
which makes the image go full screen. But how do I implement zooming. Do I need to do it from scratch using gesture recognizers? Or maybe there's a default image display view with all that implemented I am not aware of?
i have create this effect for one of my app, dont forget to set delegate of your scrollview.
code for .h file
#import <UIKit/UIKit.h>
#interface ImageViewerController : UIViewController<UIScrollViewDelegate>
// The scroll view used for zooming.
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
// The image view that displays the image.
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
// The image that will be shown.
#property (strong, nonatomic) NSString *imageUrlString;
#end
code for .m
#import "ImageViewerController.h"
#interface HNImageViewerController ()
- (IBAction)handleSingleTap:(UIButton*)tapGestureRecognizer;
#end
#implementation ImageViewerController
- (void)viewDidLoad {
[super viewDidLoad];
[self.imageView setImage:[UIImage imageNamed:#"placeholder-image"]];
self.scrollView.delegate=self;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
#pragma mark - UIScrollViewDelegate methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (self.scrollView.zoomScale == self.scrollView.minimumZoomScale) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}
#pragma mark - Private methods
- (IBAction)handleSingleTap:(UIButton *)tapGestureRecognizer {
[self dismissViewControllerAnimated:YES completion:nil];
}
This is very easy to implement:
- (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer;
and then:
- (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer {
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
recognizer.scale = 1;
}
Related
I'm relatively new to Xcode, and am in the process of making an app in Objective C with several viewControllers each with a single UIScrollView containing a single UIImage that can be zoomed and scrolled.
This code works for the first image (dermatomes), but I can't figure out how to tweak the UIView to enable zooming and scrolling on the second image (anatomicPlanes). Currently the second image imports correctly to the second UIScrollView, but when I try to zoom it just jumps down and right and remains static there.
The size of the UIScrollViews were set using Interface Builder, no problems there.
viewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *dermatomeScrollView;
UIImageView *dermatomesImageView;
IBOutlet UIScrollView *anatomicPlaneScrollView;
UIImageView *anatomicPlanesImageView;
}
#property (strong, nonatomic) IBOutlet UIScrollView *dermatomeScrollView;
#property (strong, nonatomic) IBOutlet UIImageView *dermatomesImageView;
#property (strong, nonatomic) IBOutlet UIImageView *anatomicPlanesImageView;
#property (strong, nonatomic) IBOutlet UIScrollView *anatomicPlaneScrollView;
#end
viewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize dermatomeScrollView, anatomicPlanesImageView, dermatomesImageView, anatomicPlaneScrollView;
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return dermatomesImageView;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *dermatomes = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"dermatomes.jpg"]];
self.dermatomesImageView = dermatomes;
dermatomeScrollView. maximumZoomScale = 1.2;
dermatomeScrollView. minimumZoomScale = 0.4;
dermatomeScrollView. delegate = self;
[dermatomeScrollView addSubview:dermatomesImageView];
dermatomeScrollView.zoomScale = 0.6;
UIImageView *planes = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"anatomic planes.jpg"]];
self.anatomicPlanesImageView = planes;
anatomicPlaneScrollView. maximumZoomScale = 1.2;
anatomicPlaneScrollView. minimumZoomScale = 0.4;
anatomicPlaneScrollView. delegate = self;
[anatomicPlaneScrollView addSubview:anatomicPlanesImageView];
anatomicPlaneScrollView.zoomScale = 0.6;
}
Any help is appreciated!
You need to return the correct view based on the scroll view that is requesting. Every method in the delegate pattern is passed a reference to the originator of the method call, so your delegate implementation can handle it differently. In this case, the originator of the delegate method call is the scroll view:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
if (scrollView == dermatomeScrollView) {
return dermatomesImageView;
}
return anatomicPlanesImageView;
}
If you add more scrollviews, you'll have to extend this method further.
i Am using Mb Progress Bar. in which the progress bar is sccessing automatically. here i want to move the progress bar with my mouse cursor.
i am using Github Library
https://github.com/matibot/MBCircularProgressBar
This library gives me animated progress bar which runs automatically on button click. i want exactly this one. but it should not be automatically. i want to move it by my cursor like hand moment.
this is my code:::
#property (weak, nonatomic) IBOutlet MBCircularProgressBarView *progressBar;
#property (weak, nonatomic) IBOutlet UISwitch *animatedSwitch;
#end
#implementation MBViewController
- (void)viewDidLoad {
[super viewDidLoad];
// pan gesture detects circle dragging
UIPanGestureRecognizer *pv = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
//[self addGestureRecognizer:pv];
[self.progressBar addGestureRecognizer:pv];
}
- (IBAction)animate:(UIButton *)sender {
[UIView animateWithDuration:self.animatedSwitch.on * 1.f animations:^{
self.progressBar.value = 100.f - self.progressBar.value;
}];
}
# pragma mark detect pan and determine angle of pan location vs. center of circular revolution
- (void) handlePan:(UIPanGestureRecognizer *)pv {
self.progressBar.value = 100.f - self.progressBar.value;
}
Anyone can have idea. please help me for this::
I'm Making a game, with level select Ive got 3 levels and 3 views on 3 different controllers
Now I've placed 2 - 1/4 of the button on each side of my scroll view, on on the left and one on the right!
When the user of the game is on level 1 "thats View1" The button on the left needs to be hidden and only show when its on View2 and View 3 - same goes for the button on View3 on the right!
How is this done?
Outlets for those buttons are leftIllusion & rightIllusion
code for UIViews:
#implementation ViewController
#synthesize View1;
#synthesize View2;
#synthesize View3;
- (void)viewDidLoad
{
// Do any additional setup after loading the view, typically from a nib.
[super viewDidLoad];
[self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"View1"]];
[self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"View2"]];
[self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:#"View3"]];
}
code from that imports scroll file .h:
#import "PagerViewController.h"
#interface ViewController : PagerViewController {
}
#property (strong, nonatomic) IBOutlet UIView *View1;
#property (strong, nonatomic) IBOutlet UIView *View2;
#property (strong, nonatomic) IBOutlet UIView *View3;
#end
UIScrollView instance has property contentOffset, which can help you to detect what view is being displayed now (view1, view2, view3). I am posting example code-snippet, which helps me to determine the page number of scrollView.
- (NSInteger)pageNumber
{
static NSInteger previousPage = 0;
CGFloat pageWidth = self.scrollView.frame.size.width;
float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
NSLog(#"page number %d",page);
if (previousPage != page) {
previousPage = page;
/* Page did change */
//put here your hide/show buttons logics
}
return page;
}
The best place to insert these lines is scrollView delegate's method -(void)scrollViewDidEndDecelerating:. The scroll view calls this method each time when the scrolling movement comes to a halt.
So your final version will look like:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender
{
[self pageNumber];
}
When the user zooms far enough out of the image by pinching out, then releases, I want it to close the UIImageView/scroll view, basically exiting the picture viewer.
How would I go about doing this? scrollViewDidEndZooming is called after it animates back into place, so I can't use that, and none of the other delegate methods seem helpful.
i have create this effect for one of my app, dont forget to set delegate of your scrollview.
you need to update the private method with your pinch gesture(thats all)
code for .h file
#import <UIKit/UIKit.h>
#interface ImageViewerController : UIViewController<UIScrollViewDelegate>
// The scroll view used for zooming.
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
// The image view that displays the image.
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
// The image that will be shown.
#property (strong, nonatomic) NSString *imageUrlString;
#end
code for .m
#import "ImageViewerController.h"
#interface HNImageViewerController ()
- (IBAction)handleSingleTap:(UIButton*)tapGestureRecognizer;
#end
#implementation ImageViewerController
- (void)viewDidLoad {
[super viewDidLoad];
[self.imageView setImage:[UIImage imageNamed:#"placeholder-image"]];
self.scrollView.delegate=self;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
#pragma mark - UIScrollViewDelegate methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (self.scrollView.zoomScale == self.scrollView.minimumZoomScale) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}
#pragma mark - Private methods
- (IBAction)handleSingleTap:(UIButton *)tapGestureRecognizer {
[self dismissViewControllerAnimated:YES completion:nil];
}
i have my button, created from storyboard:
#property (weak, nonatomic) IBOutlet UIButton *plusOneBtnPoisonTwo;
with its method:
- (IBAction)plusOnePlayerTwoPoison:(id)sender;
then I check device rotation and set new position:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// NSLog(#"%d", toInterfaceOrientation);
if(!UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
self.plusOneBtnPoisonTwo.center = CGPointMake(284, 406);
}
}
the button moves in the new position, but the method plusOnePlayerTwoPoison is no more triggered...
Any Idea?
Thanks.
Try using this instead. Its just a guess that it may resolve your problem.
#property (retain, nonatomic) IBOutlet UIButton *plusOneBtnPoisonTwo; //change to retain
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//add button action manually by code
[plusOneBtnPoisonTwo addTarget:self action:#selector(plusOnePlayerTwoPoison:) forControlEvents:UIControlEventTouchDown];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// NSLog(#"%d", toInterfaceOrientation);
if(!UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
[plusOneBtnPoisonTwo setFrame:CGRectMake(284, 406,50,100)];
}
}