UIScrollView + UIImage and zoom: not fluid - objective-c

I have view controller, and inside that I have a UIScrollView, for managing the zoom, and a UIImage.
Now I'm handling the zoom effect with UIScrollViewDelegate delegate and method viewForZoomingInScrollView:... but the result is very poor, definitely not fluid!
This is my code:
#import "ImageViewController.h"
#interface ImageViewController () <UIScrollViewDelegate, UIActionSheetDelegate>
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#end
#implementation ImageViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView.delegate = self;
self.scrollView.maximumZoomScale = 3.0;
// some code
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
// last update
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
if ([self.scrollView zoomScale] < 1.0) {
[self.scrollView setZoomScale:1.0];
}
}
// some other methods...
#end
This is the storyboard view:
I'm not using a Pinch Gesture Recognizer.
All images are quite small like 640x480.
Thanks
P.S. this is a continue of UICollectionView and images.

Checkout out this tutorial I wrote. The first part is exactly what you need to implement.

This has been addressed in other posts:
Zooming image views with autolayout:
Centering logic for autolayout or springs and struts

Related

Building a Camera Application... UIScrollView will not zoom

I'm building a camera application, and I can't get the zooming on the image to work. I honestly don't know where to go from here, I'm sure it's some dumb mistake that I'm missing though. The app sets the chosenImageView to the workingImage (picture from the camera). When I try to zoom, nothing happens.
ViewController.h
#interface ViewController : UIViewController <UIActionSheetDelegate, UIImagePickerControllerDelegate, UIScrollViewDelegate>
#property (strong, nonatomic) UIImage *workingImage;
#property (weak, nonatomic) IBOutlet UIImageView *chosenImageView;
#property (weak, nonatomic) IBOutlet UIScrollView *imageScroller;
-(IBAction)cameraButtonPressed;
#end
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.imageScroller.minimumZoomScale = 0.01f;
self.imageScroller.maximumZoomScale = 6.0f;
self.imageScroller.contentSize = self.imageScroller.frame.size;
self.imageScroller.scrollEnabled = YES;
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.chosenImageView;
}
Here was the problem. You have to control+drag from the UIScrollView to the View Controller to set the delegate.

UIScrollView goes crazy when zooming?

I've tried searching for answers for this, but I have no idea what to search for and I'm at wit's end. I've got a UIScrollView that, when zooming, completely flips out and the image glitches everywhere before disappearing entirely. It even manages to, on occasion, temporarily screw up other components that aren't even part of the UIScrollView in which the zooming is happening. I apologize I can't be more technical. I wouldn't even know which part of my code to look at.
I made a video, because I have no technical terminology to describe what's happening here. Any help would be appreciated.
https://www.youtube.com/watch?v=SvhqHI-3_g8
The red is my current background of the UIScrollView. Don't mind that.
ViewController.h
#interface ViewController : UIViewController <UIActionSheetDelegate, UIImagePickerControllerDelegate, UIScrollViewDelegate>
#property (strong, nonatomic) UIImage *workingImage;
#property (weak, nonatomic) IBOutlet UIImageView *chosenImageView;
#property (weak, nonatomic) IBOutlet UIScrollView *imageScroller;
-(IBAction)cameraButtonPressed;
#end
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.imageScroller.minimumZoomScale = 1.00f;
self.imageScroller.maximumZoomScale = 15.0f;
self.imageScroller.contentSize = self.imageScroller.frame.size;
self.imageScroller.scrollEnabled = YES;
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.chosenImageView;
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *chosenImage = [info objectForKey:UIImagePickerControllerOriginalImage];
[self.chosenImageView setImage:chosenImage];
[self.imageScroller setContentSize:chosenImage.size];
[self dismissViewControllerAnimated:YES completion:nil];
}
See if this article helps. It seems the missing ScrollViewDidZoom method might be key to maintaining the zoomed view in place. http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content

Adding a UIButton to a UIScrollView stops it from scrolling

I'm very new to programming and objective C so you'll have to go easy on me. I'm sure some of the code in the app is probably unnecessary. I've searched google and StackOverflow for an answer but none of the solutions have worked for me, either because they're not the right solution or I just misunderstand the answers.
The problem is that when I add an image that is very long and I want to scroll ONLY vertically, it initially refuses to scroll until I change a "constraint" called "Vertical Space (-1678) - Scroll View - Image View - Ruler pic.png" to 0 for a reason unknown to me. I don't even understand why it defaults it as -1678.
Anyway, it then works perfectly until I add a UIButton in the storyboard (to which I later want to add a modal "action segue" so that it will go to another view). When I've added UIButton it won't scroll at all in the simulator.
I suppose I must have done something wrong because I've only entered one line of code (declaring it) regarding the button, or maybe I have to put some more code in for it to scroll. I don't know! If you need more information in order to help I'll be happy to provide it. I'm fed up with trying to make it work. Thanks in advance.
ViewController.h
#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
#interface ViewController : UIViewController <ADBannerViewDelegate, UIScrollViewDelegate> {
ADBannerView *adView;
BOOL bannerIsVisible;
IBOutlet UIScrollView *scrollView;
IBOutlet UIImageView *imageView;
IBOutlet UIButton *proVersion;
}
#property (nonatomic, assign) BOOL bannerIsVisible;
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize bannerIsVisible;
#synthesize scrollView;
#synthesize imageView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Hide status bar:
[[UIApplication sharedApplication] setStatusBarHidden:YES];
// iAd:
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
adView.frame = CGRectOffset(adView.frame, 0, -50.0f);
[self.view addSubview:adView];
adView.delegate=self;
self.bannerIsVisible=NO;
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!self.bannerIsVisible) {
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, 50.0f);
[UIView commitAnimations];
self.bannerIsVisible = YES;
}
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (self.bannerIsVisible) {
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, -50.0f);
[UIView commitAnimations];
self.bannerIsVisible = NO;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I played around a bit and fiddled around with the example in the answer and I got to this code:
scrollView.contentSize = CGSizeMake(320,2246);
which worked! I spent days working on this and it was just one blasted little line of code. I put it into the viewDidLoad and all of a sudden it was scrolling. I also had to turn of "AutoLayout".
You will need to set the ContentSize of the ScrollView, like this:
[scrollView setContentSize:CGSizeMake(320, 500)];

How do I switch between 2 image using UISegmentcontrol?

I've tried writing this code but I don't think it's correct cause there is an error with the viewDidLoad.
I'm trying to switch between 2 images in the same UIImageView using UISegmentcontol using Storyboard. All the examples online are for switching labels and not using Xcode storyboard.
h.file
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
IBOutlet UIImageView *myImage;
IBOutlet UISegmentedControl *segControl;
}
#property(nonatomic, retain)IBOutlet UIImageView *myImage;
#property (nonatomic, retain)IBOutlet UISegmentedControl *segControl;
- (IBAction)switchButton:(id)sender;
#end
m.file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myImage;
#synthesize segControl;
- (IBAction)switchButton:(id)sender
{
if (segControl.selectedSegmentIndex == 0)
{
[myImage setImage:[UIImage imageNamed:#"image1.jpg"]];
}
else
if (segControl.selectedSegmentIndex == 1)
{
[myImage setImage:[UIImage imageNamed:#"image2.jpg"]];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *myImage = [myImage setImage:[UIImage imageNamed:#"image1.jpg"]];
}
If you want to fill the segments of the segmented control with images, you don't need code. Just use the storyboard.

Why isn't my UIButton responding to touches?

I'm sure I'm overlooking the obvious as I've got countless working buttons...but...for whatever reason this one is not cooperating...
I've added a UIButton (Rounded Rect) to a UIView subclass (DialogView) which is a subview of my view controller's view. This subview is created almost entirely in IB. I've wired up the button to (IBAction)okButtonPressed:(id)sender in IB to Touch Up Inside and created a corresponding method in DialogView. However when I "touch" this button it doesn't trigger the method. userInteractionEnabled is true for the VC's view, DialogView and the UIButton.
Thinking maybe initWithCoder had to do some frame manipulation or something I added the following which successfully logs to console.
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
NSLog(#"DialogView initWithCoder called");
}
return self;
}
In further exploration I wired up an IBOutlet to the button and then if I try to change the titleLabel from the view controller I notice that it get's severely truncated. Default text of say "Press Me!" set in IB displays fine when view is first drawn. But if I change the text...
self.DialogView.okButton.titleLabel.text = #"Not Working";
...it gets truncated to "N..."
Dunno if this is related. Probably...
Anyone see what I've screwed up here?
Edit (adding code related to showing UIButton):
From the View Controller:
self.DialogView = [[[NSBundle mainBundle] loadNibNamed:#"DialogView" owner:self options:nil] objectAtIndex:0];;
self.DialogView.myVC = self;
self.DialogView.backgroundColor = [UIColor clearColor];
self.DialogView.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
self.DialogView.nameLabel.text = loan.fullName;
self.DialogView.noteLabel.text = loan.summaryOfLoan;
self.DialogView.amountLabel.text = [currencyFormatter stringFromNumber:loan.originalAmount];
self.DialogView.alpha = 0.0;
[self.view addSubview:DialogView];
The UILabels all displaying as expected. As is the problem UIButton. I can see it I just can't interact with it!?!
DialogView's interface:
#class MyViewController;
#interface DialogView : UIView {
IBOutlet UILabel *nameLabel, *noteLabel, *amountLabel;
IBOutlet UIImageView *arrowView;
IBOutlet UIButton *okButton;
MyViewController *myVC;
}
#property (nonatomic, retain) UILabel *nameLabel, *noteLabel, *amountLabel;
#property (nonatomic, retain) UIImageView *arrowView;
#property (nonatomic, assign) MyViewController *myVC;
#property (nonatomic, retain) UIButton *okButton;
- (IBAction)okButtonPressed:(id)sender;
#end
And DialogView's implementation:
#import "DialogView.h"
#import "MyViewController.h"
#implementation DialogView
#synthesize nameLabel, noteLabel, amountLabel, arrowView, okButton;
#synthesize myVC;
- (void)dealloc {
[nameLabel release];
[noteLabel release];
[amountLabel release];
[arrowView release];
[okButton release];
[super dealloc];
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
NSLog(#"DialogView initWithCoder called");
}
return self;
}
- (IBAction)okButtonPressed:(id)sender {
NSLog(#"pressed DialogView OK button");
[self.myVC.navigationController popViewControllerAnimated:YES];
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
#end
I thought that we should use -setTitle:forState: in order to set button's title ?
An other thought, did you check that the button's frame is not CGRectZero ? And by the way, all the frames for the view in the hierarchy ? And check that one superview in the hierarchy is not user interaction disabled ?
And, I think imageView does not respond to touches, do you have one in your code ?
I was just having more or less the same problem and I found that my containing view did not have "User Interaction Enabled".
Hope this helps.
Do you maybe have two buttons on top of one another? Change the IB project window to the detail view and see if your view has more buttons than you are expecting. Maybe you've wired up a button that's not actually getting the press you're expecting.