如何在 ScrollView (iPhone) 中启用缩放
Posted
技术标签:
【中文标题】如何在 ScrollView (iPhone) 中启用缩放【英文标题】:How to enable Zooming in ScrollView (iPhone) 【发布时间】:2011-03-17 22:13:32 【问题描述】:我有一个代码,我想修改它以获得缩放功能。现在我的应用只做水平滚动而不做缩放。
我错过了一些东西,因为我尝试了“viewForZoomingInScrollView:”但没有成功。 我怎样才能放大这个?
谢谢
#import <UIKit/UIKit.h>
@interface IntroductionViewController : UIViewController <UIScrollViewDelegate>
IBOutlet UIScrollView *scrollView;
CGRect rectScrollView;
int scrollWidth;
int scrollHeight;
NSArray *contentArray;
UIColor *bcgColor;
BOOL rememberPosition;
NSString *positionIdentifier;
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
/// returns width of the scollview
- (int)getScrollViewWidth;
/// set width and height for your final UIScrollView
- (void)setWidth:(int)width andHeight:(int)height;
/// set the exactly same size as it is your parent view
- (void)setSizeFromParentView:(UIScrollView *)scView;
/// set background color for your UIScrollView
- (void)setBackGroudColor:(UIColor *)color;
/// set an array with images you want to display in your new scroll view
- (void)setContentArray:(NSArray *)images;
/// enable position history
- (void)enablePositionMemory;
/// enable position history with custom memory identifier
- (void)enablePositionMemoryWithIdentifier:(NSString *)identifier;
/// returns your UIScrollView with predefined page
- (UIScrollView *)getWithPosition:(int)page;
/// returns your UIScrollView with enabled position history
- (UIScrollView *)getWithPositionMemory;
/// returns your UIScrollView with enabled position history with custom memory identifier
- (UIScrollView *)getWithPositionMemoryIdentifier:(NSString *)identifier;
/// returns your UIScrollView
- (UIScrollView *)get;
@end
和实施:
#import "IntroductionViewController.h"
#define kIGUIScrollViewImagePageIdentifier @"kIGUIScrollViewImagePageIdentifier"
#define kIGUIScrollViewImageDefaultPageIdentifier @"Default"
@implementation IntroductionViewController
@synthesize scrollView;
- (int)getScrollViewWidth
return ([contentArray count] * scrollWidth);
- (void)setWidth:(int)width andHeight:(int)height
scrollWidth = width;
scrollHeight = height;
if (!width || !height) rectScrollView = [[UIScreen mainScreen] applicationFrame];
else rectScrollView = CGRectMake(0, 0, width, height);
- (void)setSizeFromParentView:(UIScrollView *)scView
scrollWidth = scView.frame.size.width;
scrollHeight = scView.frame.size.height;
rectScrollView = CGRectMake(0, 0, scrollWidth, scrollHeight);
- (void)setContentArray:(NSArray *)images
contentArray = images;
- (void)setBackGroudColor:(UIColor *)color
bcgColor = color;
- (void)enablePositionMemoryWithIdentifier:(NSString *)identifier
rememberPosition = NO;
if (!identifier) identifier = kIGUIScrollViewImageDefaultPageIdentifier;
positionIdentifier = identifier;
- (void)enablePositionMemory
[self enablePositionMemoryWithIdentifier:nil];
- (UIScrollView *)getWithPosition:(int)page
if (!contentArray)
contentArray = [[[NSArray alloc] init] autorelease];
if (page > [contentArray count]) page = 0;
if (!scrollWidth || !scrollHeight)
rectScrollView = [[UIScreen mainScreen] applicationFrame];
scrollWidth = rectScrollView.size.width;
scrollHeight = rectScrollView.size.height;
rectScrollView = CGRectMake(0, 0, scrollWidth, scrollHeight);
self.scrollView = [[UIScrollView alloc] initWithFrame:rectScrollView];
self.scrollView.contentSize = CGSizeMake([self getScrollViewWidth], scrollHeight);
if (!bcgColor) bcgColor = [UIColor blackColor];
self.scrollView.backgroundColor = bcgColor;
self.scrollView.alwaysBounceHorizontal = YES;
self.scrollView.contentOffset = CGPointMake(page * scrollWidth, 0);
self.scrollView.pagingEnabled = YES;
UIView *main = [[[UIView alloc] initWithFrame:rectScrollView] autorelease];
int i = 0;
for (UIImage *img in contentArray)
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = img;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
imageView.backgroundColor = [UIColor blackColor];
float ratio = img.size.width/rectScrollView.size.width;
CGRect imageFrame = CGRectMake(i, 0, rectScrollView.size.width, (img.size.height / ratio));
imageView.frame = imageFrame;
[self.scrollView addSubview:(UIView *)imageView];
i += scrollWidth;
[imageView release];
[main addSubview:scrollView];
//if (margin) [margin release];
[self.scrollView release];
[self.scrollView release];
return (UIScrollView *)main;
- (UIScrollView *)get
return [self getWithPosition:0];
- (UIScrollView *)getWithPositionMemory
[self enablePositionMemory];
return [self getWithPosition:[[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"%@%@", kIGUIScrollViewImagePageIdentifier, kIGUIScrollViewImageDefaultPageIdentifier]] intValue]];
- (UIScrollView *)getWithPositionMemoryIdentifier:(NSString *)identifier
[self enablePositionMemoryWithIdentifier:identifier];
return [self getWithPosition:[[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"%@%@", kIGUIScrollViewImagePageIdentifier, positionIdentifier]] intValue]];
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sv
int page = sv.contentOffset.x / sv.frame.size.width;
if (rememberPosition)
[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithFormat:@"%d", page] forKey:[NSString stringWithFormat:@"%@%@", kIGUIScrollViewImagePageIdentifier, positionIdentifier]];
[[NSUserDefaults standardUserDefaults] synchronize];
- (NSArray *)getImages
NSMutableArray *arr = [[[NSMutableArray alloc] init] autorelease];
// codice per intercettare la lingua impostata dall utente
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
NSString *currentLanguage = [languages objectAtIndex:0];
NSLog(@"Codice lingua %@", currentLanguage);
if( [currentLanguage isEqualToString:@"es"] )
[arr addObject:[UIImage imageNamed:@"image1-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image2-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image3-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image4-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image5-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image6-intro.jpg"]];
return (NSArray *)arr;
else
[arr addObject:[UIImage imageNamed:@"image1-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image2-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image3-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image4-intro.jpg"]];
[arr addObject:[UIImage imageNamed:@"image5-intro.jpg"]];
return (NSArray *)arr;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
// Custom initialization
return self;
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
[super viewDidLoad];
//codice per mettere il titolo come immagine
UIImage *titolo = [UIImage imageNamed: @"introTitle.png"];
UIImageView *titoloView = [[UIImageView alloc] initWithImage: titolo];
self.navigationItem.titleView = titoloView;
IntroductionViewController *svimage = [[IntroductionViewController alloc] init];
[svimage setContentArray:[self getImages]];
[svimage setSizeFromParentView:scrollView];
[self.view addSubview:[svimage getWithPosition:0]];
[svimage release];
[titoloView release];
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
*/
- (void)didReceiveMemoryWarning
NSLog(@"memoria view");
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
- (void)viewDidUnload
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
- (void)dealloc
[super dealloc];
@end
【问题讨论】:
请格式化您的代码。 【参考方案1】:您在哪里实现 viewForZoomingInScrollView? 它返回什么?
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
return yourViewToBeZoomed; //
编辑:
好的,所以,一般来说,使用此方法,您只需指定当用户在您的 scrollView 上使用广告移动 2 个手指时您必须滚动的内容...通常(但并非总是)它是 UIScrollView 本身的第一个子视图。 .
所以,如果是您的情况,请尝试以下代码:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
return [scrollView2.subviews objectAtIndex:0];
如果您添加了更多 subView 并且也想缩放它们,您最好不要直接将它们添加到您的 UIScrollView 而是添加到您的第一个 subView,这样它们就会随之缩放...
知乎,
卢卡
【讨论】:
在我放在这里的代码中没有,但这就是问题所在,我必须使用什么视图?- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView return ??; //
@andrea:好的,我正在添加一个新的编辑,在一两分钟内看看我的旧答案...... ciao
我试过- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView return [scrollView.subviews objectAtIndex:0];
,但它没有工作它给了ma一个“本地声明”scrollView“隐藏实例变量。所以我试过- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView return [self.scrollView.subviews objectAtIndex:0]; NSLog(@"zoom");
但它不起作用,它不能缩放
@andrea: 好的,它隐藏了它,因为你有一个同名的属性,你的代码应该可以工作,或者你可以更改方法的参数名称:(UIScrollView *)scrollView -> (UIScrollView *)scrollView2 并返回 [scrollView2.subviews objectAtIndex:0]; ...但是要检查是否调用了该方法,您必须将 NSLog 行放在 RETURN 行之前(“return”停止该方法)...
@andrea: PS:但是你的类中的所有其他 您是否设置了最大缩放比例?无论是在代码中,还是在 IB 中……
【讨论】:
是的,但我的问题是我为图像创建了一个数组,然后将该数组放入 ViewDidLoad 中。当我必须使用这种方法时,我将在里面使用什么视图? - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView return XXX 【参考方案3】:这有效,Photoscroller Apple 示例,它也使用了 Tiling,但您可以禁用它(竞争或只是禁用白线)。它还支持旋转。
这里是你可以使用普通图像而不是平铺的地方:
- (void)configurePage:(ImageScrollView *)page forIndex:(NSUInteger)index
page.index = index;
page.frame = [self frameForPageAtIndex:index];
// Use tiled images
/*
[page displayTiledImageNamed:[self imageNameAtIndex:index]
size:[self imageSizeAtIndex:index]];
*/
// To use full images instead of tiled images, replace the "displayTiledImageNamed:" call
// above by the following line:
[page displayImage:[self imageAtIndex:index]];
如果您想使用平铺(用于大图像)但不想看到白线,这里是代码(在 ImageScrollView 中):
- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize
// clear the previous imageView
[imageView removeFromSuperview];
[imageView release];
imageView = nil;
// reset our zoomScale to 1.0 before doing any further calculations
self.zoomScale = 1.0;
// make a new TilingView for the new image
imageView = [[TilingView alloc] initWithImageName:imageName size:imageSize];
/*
[(TilingView *)imageView setAnnotates:YES]; // ** remove this line to remove the white tile grid **
*/
[self addSubview:imageView];
self.contentSize = imageSize;
[self setMaxMinZoomScalesForCurrentBounds];
self.zoomScale = self.minimumZoomScale;
【讨论】:
以上是关于如何在 ScrollView (iPhone) 中启用缩放的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iPhone SDK 中单击按钮时水平滚动 ScrollView
Android 中 ScrollView 如何实现类似 iPhone 中 UIScrollView 的分页功能?
Scrollview 不显示其内容的顶部而不在 iphone 应用程序中向下滚动