IPhone-全屏UIScrollView从右开始,但将自身重新定位到导航栏下方
我目前正试图实现一个照片选择器,就像照片应用程序一样,但有一个自定义的图像源。 对于“照片滚动”部分,我使用了Apple PhotoScroller示例代码并对其进行了修改。主要区别之一是,它现在嵌入了导航控制器(photoPicker自己的导航控制器,而不是应用程序的导航控制器)中,并带有导航条。 我的状态和导航栏是半透明的,我在photoPicker中使用的所有视图控制器上都设置了WantFullScreenLayout=YES。它似乎工作得很好。“概览”视图(显示相册所有照片的缩略图的视图)确实是全屏的,我必须手动对其进行偏移,以便首先在导航栏下显示缩略图。 然而,对于滚动部分,存在一个小故障。 对于那些不了解photoScroller示例代码的人,它可以与具有UIScrollView属性(pagingScrollView)的自定义UIViewController(PhotoViewController)以及具有UIView和NSInteger索引属性的一组自定义UIScrollView(ImageScrollView)一起使用。然后将ImageScrollView实例作为PhotoScroller的子视图添加/删除 以下是一些相关代码: PhotoViewController.hIPhone-全屏UIScrollView从右开始,但将自身重新定位到导航栏下方,iphone,fullscreen,offset,scrollview,navigationbar,Iphone,Fullscreen,Offset,Scrollview,Navigationbar,我目前正试图实现一个照片选择器,就像照片应用程序一样,但有一个自定义的图像源。 对于“照片滚动”部分,我使用了Apple PhotoScroller示例代码并对其进行了修改。主要区别之一是,它现在嵌入了导航控制器(photoPicker自己的导航控制器,而不是应用程序的导航控制器)中,并带有导航条。 我的状态和导航栏是半透明的,我在photoPicker中使用的所有视图控制器上都设置了WantFullScreenLayout=YES。它似乎工作得很好。“概览”视图(显示相册所有照片的缩略图的视图
@interface PhotoViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *pagingScrollView;
NSMutableSet *recycledPages;
NSMutableSet *visiblePages;
IBOutlet UIToolbar *toolbar;
IBOutlet UIBarButtonItem *previousButtonItem;
IBOutlet UIBarButtonItem *nextButtonItem;
id<PhotoViewDataSource> dataSource;
}
@property(nonatomic, retain) UIScrollView *pagingScrollView;
@property(nonatomic, retain) NSMutableSet *recylcledPages;
@property(nonatomic, retain) NSMutableSet *visiblePages;
@property(nonatomic, retain) UIToolbar *toolbar;
@property(nonatomic, retain) UIBarButtonItem *previousButtonItem;
@property(nonatomic, retain) UIBarButtonItem *nextButtonItem;
@property(nonatomic, retain) id<PhotoViewDataSource> dataSource;
界面PhotoViewController:UIViewController{
UIScrollView*分页ScrollView;
NSMutableSet*可回收页面;
NSMutableSet*可见页面;
ibuitoolbar*工具栏;
IBUIBarbuttonItem*以前的Buttonitem;
IBUIBAButtonim*下一个Buttonim;
id数据源;
}
@属性(非原子,保留)UIScrollView*pagingScrollView;
@属性(非原子,保留)NSMutableSet*recylcledPages;
@属性(非原子,保留)NSMutableSet*visiblePages;
@属性(非原子,保留)UIToolbar*工具栏;
@属性(非原子,保留)UIBarButtonItem*以前的buttonitem;
@属性(非原子,保留)uibarbuttonite*nextbuttonite;
@属性(非原子,保留)id数据源;
PhotoViewController.m
- (void)loadView
{
self.wantsFullScreenLayout = YES;
// Configure the scrollView
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor redColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = CGSizeMake(pagingScrollViewFrame.size.width * [self.dataSource imageCount],
pagingScrollViewFrame.size.height);
//pagingScrollView.contentOffset = CGPointMake(0, 0);
pagingScrollView.delegate = self;
self.view = pagingScrollView;
// TODO ? Prepare to tile content
recycledPages = [[NSMutableSet alloc] init];
visiblePages = [[NSMutableSet alloc] init];
[self processPages];
}
- (void)processPages {
// Calculate which pages are visible
CGRect visibleBounds = pagingScrollView.bounds;
NSLog(@"PhotoViewController - processPages : frame = %@", NSStringFromCGRect(pagingScrollView.frame));
NSLog(@"pagingScrollView bounds = %@", NSStringFromCGRect(pagingScrollView.bounds));
NSLog(@"and contentSize = %@", NSStringFromCGSize(pagingScrollView.contentSize));
int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
int lastNeededPageIndex = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));
firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
lastNeededPageIndex = MIN(lastNeededPageIndex, [dataSource imageCount] - 1);
if (lastNeededPageIndex >= 0) {
// Recycle no-longer-visible pages
for (ImageScrollView *page in visiblePages) {
if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
[recycledPages addObject:page];
[page removeFromSuperview];
}
}
[visiblePages minusSet:recycledPages];
// add missing pages
for (int index = firstNeededPageIndex; index <= lastNeededPageIndex; index++) {
if (![self isDisplayingPageForIndex:index]) {
ImageScrollView *page = [self dequeueRecycledPage];
if (page == nil) {
page = [[[ImageScrollView alloc] init] autorelease];
}
[self configurePage:page forIndex:index];
NSLog(@"PhotoViewController - processPage 2 : bounds = %@", NSStringFromCGRect(pagingScrollView.bounds));
[pagingScrollView addSubview:page];
NSLog(@"PhotoViewController - processPage 3 : bounds = %@", NSStringFromCGRect(pagingScrollView.bounds));
[visiblePages addObject:page];
}
}
}
}
- (ImageScrollView *)dequeueRecycledPage {
ImageScrollView *page = [recycledPages anyObject];
if (page) {
[[page retain] autorelease];
[recycledPages removeObject:page];
}
return page;
}
- (BOOL)isDisplayingPageForIndex:(NSUInteger)index {
BOOL foundPage = NO;
for (ImageScrollView *page in visiblePages) {
if (page.index == index) {
foundPage = YES;
break;
}
}
return foundPage;
}
- (void)configurePage:(ImageScrollView *)page forIndex:(NSUInteger)index {
page.index = index;
page.frame = [self frameForPageAtIndex:index];
NSLog(@"PhotoViewController - configurePage : bounds = %@", NSStringFromCGRect(pagingScrollView.bounds));
[page displayImage:[dataSource imageForImageId:index]];
NSLog(@"PhotoViewController - configurePage 2 : bounds = %@", NSStringFromCGRect(pagingScrollView.bounds));
}
#pragma mark -
#pragma mark ScrollView delegate methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self processPages];
}
#pragma mark -
#pragma mark Frame calculations
#define PADDING 10
- (CGRect)frameForPagingScrollView {
CGRect frame = [[UIScreen mainScreen] bounds];
frame.origin.x -= PADDING;
frame.size.width += (2*PADDING);
return frame;
}
- (CGRect)frameForPageAtIndex:(NSUInteger)index {
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
CGRect pageFrame = pagingScrollViewFrame;
pageFrame.size.width -= (2 * PADDING);
pageFrame.origin.x = (pagingScrollViewFrame.size.width * index) + PADDING;
//pageFrame.origin.x = (pagingScrollViewFrame.size.width * index) - (PADDING*index*2);
return pageFrame;
}
-(无效)加载视图
{
self.wantsFullScreenLayout=是;
//配置滚动视图
CGRect pagingScrollViewFrame=[self-frameForPagingScrollView];
pagingScrollView=[[UIScrollView alloc]initWithFrame:pagingScrollViewFrame];
pagingScrollView.PaginEnabled=是;
pagingScrollView.backgroundColor=[UIColor redColor];
pagingScrollView.showsVerticalScrollIndicator=否;
pagingScrollView.ShowShorizontalScrolIndicator=否;
pagingScrollView.contentSize=CGSizeMake(pagingScrollViewFrame.size.width*[self.dataSource imageCount],
pagingScrollViewFrame.尺寸.高度);
//pagingScrollView.contentOffset=CGPointMake(0,0);
pagingScrollView.delegate=self;
self.view=分页CrollView;
//TODO?准备平铺内容
recycledPages=[[NSMutableSet alloc]init];
visiblePages=[[NSMutableSet alloc]init];
[自我处理网页];
}
-(作废)处理页{
//计算哪些页面是可见的
CGRect visibleBounds=pagingScrollView.bounds;
NSLog(@“PhotoViewController-processPages:frame=%@”,NSStringFromCGRect(pagingScrollView.frame));
NSLog(@“pagingScrollView边界=%@”,NSStringFromCGRect(pagingScrollView.bounds));
NSLog(@“和contentSize=%@),NSStringFromCGSize(pagingScrollView.contentSize));
int firstneedpageindex=floorf(CGRectGetMinX(visibleBounds)/CGRectGetWidth(visibleBounds));
int lastNeedPageIndex=floorf((CGRectGetMaxX(visibleBounds)-1)/CGRectGetWidth(visibleBounds));
firstNeedPageIndex=MAX(firstNeedPageIndex,0);
LastNeedPageIndex=MIN(LastNeedPageIndex[dataSource imageCount]-1);
如果(LastNeedPageIndex>=0){
//回收不再可见的页面
用于(可视页面中的ImageScrollView*页面){
如果(page.indexlastneedpageindex){
[recycledPages添加对象:页面];
[page removeFromSuperview];
}
}
[visiblePages minusSet:recycledPages];
//添加缺少的页面
for(int index=firstneedpageindex;indexThree20有一个非常好的实现。如果您需要任何奇特的功能,它只需要根据您自己的需要修改代码
所有的艰苦工作都已经完成了。尽管如果你仍然想实现自己的版本,至少看一下Three20代码,看看它们是如何实现你想要实现的目标的
它看起来是什么样子:
源代码:在您的特定情况下(即,PhotoViewController
被推到UINavigationController
堆栈上)-导航栏向PhotoViewController
的滚动视图添加contentInset
。这是更好的解释和说明
也就是说,PhotoViewController
视图与窗口边界不紧密匹配,因此有空间向各个方向滚动
我找到了两种解决你问题的可能方法
1-您需要手动调整PagingCrollView的contentInset
,以补偿导航栏和状态栏的高度。将其添加到PhotoViewController
:
- (void)viewDidLoad {
[super viewDidLoad];
CGFloat topOffset = self.navigationController.navigationBar.frame.size.height + [[UIApplication sharedApplication] statusBarFrame].size.height;
pagingScrollView.contentInset = UIEdgeInsetsMake(-topOffset, 0.0, 0.0, 0.0);
}
或
2-由于只有滚动视图具有contentInset
,因此将pagingScrollView
包装为普通ui视图
:
- (void)loadView {
[self setWantsFullScreenLayout:YES];
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
photoView = [[UIView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
// ... configure the pagingScrollView
[photoView addSubview:pagingScrollView];
self.view = photoView;
// ...
}
希望这会有所帮助!需要在视图控制器中设置的主要内容如下。在内容视图中使用自动调整大小标志。启用以下标志将将视图控制器的大小扩展到屏幕的完整大小。我在ViewWillDisplay中执行以下操作
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setWantsFullScreenLayout:YES]; // if you want to underlap status
self.navigationController.navigationBar.translucent = YES; // underlap nav controller
self.toolbar.translucent = YES; // if you have a toolbar.
}
更多详细信息可在苹果的文档中找到:
如果你一直在做一些事情来设置内容视图的框架边界,我会删除所有代码,因为上面的代码应该会帮你处理好
- (void)loadView {
[self setWantsFullScreenLayout:YES];
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
photoView = [[UIView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
// ... configure the pagingScrollView
[photoView addSubview:pagingScrollView];
self.view = photoView;
// ...
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setWantsFullScreenLayout:YES]; // if you want to underlap status
self.navigationController.navigationBar.translucent = YES; // underlap nav controller
self.toolbar.translucent = YES; // if you have a toolbar.
}