【问题标题】:UIScrollView Zooming Crashes App with Exc_Bad_Access带有 Exc_Bad_Access 的 UIScrollView 缩放应用程序崩溃
【发布时间】:2012-06-21 02:34:12
【问题描述】:

当我尝试滚动 UIScrollView 时,我在 main 中收到 Exc_Bad_Access 错误。这个程序很简单。我在 AppDelegate 中添加了一个 UIViewController。然后,这是 ViewController 中的代码。这适用于滚动,但只要我添加tmpScrollView.delegate = self。当我尝试缩放时,程序不会滚动或缩放,并给我 Exc_Bad_Access 错误。

@interface MainViewController : UIViewController &ltUIScrollViewDelegate>
@property (nonatomic,retain) UIScrollView *tmpScrollView;
@property (nonatomic,retain) UIView *containerView;
@end

- (void)viewDidLoad
{
[super viewDidLoad];

// Do any additional setup after loading the view.
tmpScrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
tmpScrollView.delegate = self;
[self.view addSubview:tmpScrollView];

// Set up the container view to hold our custom view hierarchy
CGSize containerSize = CGSizeMake(640.0f, 640.0f);
self.containerView = [[UIView alloc] initWithFrame:(CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=containerSize}];
[self.tmpScrollView addSubview:self.containerView];

// Set up custom view hierarchy
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 640.0f, 80.0f)];
redView.backgroundColor = [UIColor redColor];
[self.containerView addSubview:redView];

UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 560.0f, 640.0f, 80.0f)];
blueView.backgroundColor = [UIColor blueColor];
[self.containerView addSubview:blueView];

UIView *greenView = [[UIView alloc] initWithFrame:CGRectMake(160.0f, 160.0f, 320.0f, 320.0f)];
greenView.backgroundColor = [UIColor greenColor];
[self.containerView addSubview:greenView];

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"slow.png"]];
imageView.center = CGPointMake(320.0f, 320.0f);
[self.containerView addSubview:imageView];

//Tell the scroll view the size of the contents
self.tmpScrollView.contentSize = containerSize;
}

-(void)viewWillAppear:(BOOL)animated
{
NSLog(@"Will Appear");
[super viewWillAppear:animated];

// Set up the minimum & maximum zoom scales
CGRect scrollViewFrame = self.tmpScrollView.frame;
CGFloat scaleWidth = scrollViewFrame.size.width / self.tmpScrollView.contentSize.width;
CGFloat scaleHeight = scrollViewFrame.size.height / self.tmpScrollView.contentSize.height;
CGFloat minScale = MIN(scaleWidth, scaleHeight);

self.tmpScrollView.minimumZoomScale = minScale;
self.tmpScrollView.maximumZoomScale = 1.0f;
self.tmpScrollView.zoomScale = minScale;

//***** Here is the line for setting the delegate
self.tmpScrollView.delegate = self;

[self centerScrollViewContents];
}


-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
NSLog(@"End Zoom");
}

-(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
// Return the view that we want to zoom
return self.containerView;
}

-(void)scrollViewDidZoom:(UIScrollView *)scrollView {
// The scroll view has zoomed, so we need to re-center the contents
[self centerScrollViewContents];
}
@end

感谢您的帮助。这已经让我发疯了一天......

编辑:也添加 centerScrollViewContens:

- (void)centerScrollViewContents {
    CGSize boundsSize = self.tmpScrollView.bounds.size;
    CGRect contentsFrame = self.containerView.frame;

    if (contentsFrame.size.width < boundsSize.width) {
        contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
    } else {
        contentsFrame.origin.x = 0.0f;
    }

    if (contentsFrame.size.height < boundsSize.height) {
        contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
    } else {
        contentsFrame.origin.y = 0.0f;
    }

    self.containerView.frame = contentsFrame;
}

【问题讨论】:

  • 第一行找错了,应该是:UIViewController
  • &lt 是 <.> 时最初将它写入堆栈溢出时,它没有出现。我的实际代码是

标签: iphone ios5 uiscrollview uiscrollviewdelegate


【解决方案1】:

您需要计算出滚动视图的最小缩放比例。缩放比例为 1 表示内容以正常大小显示。低于 1 的缩放比例显示缩小的内容,而大于 1 的缩放比例显示放大的内容。要获得最小缩放比例,您需要计算需要缩小多远才能使图像紧贴您的滚动视图的边界基于其宽度。然后你根据图像的高度做同样的事情。这两个结果缩放比例中的最小值将是滚动视图的最小缩放比例。这为您提供了一个缩放比例,您可以在完全缩小时看到整个图像。

斯威夫特:

let scrollViewFrame = scrollView.frame
let scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
let scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
let minScale = min(scaleWidth, scaleHeight);
scrollView.minimumZoomScale = minScale;

目标-C

CGFloat scrollViewFrame = scrollView.frame
CGFloat scaleWidth = scrollViewFrame.size.width / scrollView.contentSize.width
CGFloat scaleHeight = scrollViewFrame.size.height / scrollView.contentSize.height
CGFloat minScale = min(scaleWidth, scaleHeight);
scrollView.minimumZoomScale = minScale;

从其他项目和在 iOS 上处理大量 GPU 的个人经验(无限滚动、最大位图大小等),我注意到每个设备都有自己的阈值。对于过去的项目,我还将以下值硬编码为 minimumZoomScale 以防止崩溃:

scale :
        {
                iPad : {
                    min : 0.8
                ,   max : 1.6
            }
            , iPhone : {
                    min : 0.25
                ,   max : 1.6
            }
            , iPhone6 : {
                    min : 0.3333
                ,   max : 1.6
            }
            , iPhoneResizable: {
                    min : 1
                ,   max : 1.6
            }
        }

非常适合初学者的教程:http://www.raywenderlich.com/76436/use-uiscrollview-scroll-zoom-content-swift

【讨论】:

    【解决方案2】:

    您提供的任何代码对我来说都可以正常工作。您的“centerScrollViewContents”方法可能存在某种问题。您也可以发布此方法的代码吗???

    【讨论】:

    • 它在我的情况下仍然有效,并给出一个输出,如上方的红色视图,中间的绿色视图,最后的蓝色视图和灰色背景。尝试“清理”您的项目并重置模拟器设置然后再次运行它。或者更好地使用上述所有代码创建一个新项目并运行它。它肯定会工作。
    • 是的,我也可以看到视图。但请尝试使用 alt 键放大。当我这样做的时候。它使用 Exc_Bad_Access 进行轰炸
    • 它在我端正确缩放。你的代码绝对正确,我的朋友。你只需要重新创建一个新项目或清理你的应用程序。
    • 我实际上已经重做了一次项目。我也打扫过了。我不知道这是怎么回事...
    • 所以我制作了另一个项目并将 ScrollView 添加到带有 xib 的 UIViewController 中。然后适当地设置引用和委托,相同的代码可以正常工作。它与委托有关。
    猜你喜欢
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2013-07-16
    • 2013-10-25
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    相关资源
    最近更新 更多