如何约束UIScrollView只能垂直缩放?

时间:2011-10-28 12:27:45

标签: objective-c iphone uiscrollview xamarin.ios constraints

我有一个UIScrollView,我用它来表示图形上的轴。我希望用户能够使用通常的捏合动作放大轴,但是它只能在垂直方向上缩放,而不能在水平方向上缩放。

我的问题类似于this one,但我尝试了那里建议的解决方案(覆盖子视图的SetTransform方法,以便忽略一个方向的缩放),并且在水平约束缩放时它可以正常工作,但不能垂直。当我尝试垂直实现它时,第一个捏合动作可以正常工作,但后续捏合似乎会在缩放之前将缩放比例重置为1。

有谁知道可能导致这种行为的原因,更重要的是我如何解决这个问题?

我正在使用MonoTouch但使用Objective-C的答案很好。

4 个答案:

答案 0 :(得分:2)

我知道这个问题已经发布了很久以前,但对于任何坚持这个问题的人来说,这是一个答案。

我查看了你链接到的问题,rankAmateur,我认为修复解决方案的简单方法就是在setTransform:方法中用“d”属性替换CGAffineTransform的“a”属性

- (void)setTransform:(CGAffineTransform)newValue;
{
 CGAffineTransform constrainedTransform = CGAffineTransformIdentity;
 // constrainedTransform.a = newValue.a;
 constrainedTransform.d = newValue.d;
 [super setTransform:constrainedTransform];
}

我不太熟悉CGAffineTransorm,但这对我有用,在浏览文档后,似乎“a”属性对应于视图的x轴,“d”属性对应于视图的y轴

修改

所以在回过头来意识到问题到底是什么之后,我做了一些深入研究,我有点难过,但是经历了rankAmateur上面提到的相同行为,CGAffineTransform工作似乎非常不寻常当缩放仅限于水平,而不是仅限于垂直时,缩放适用于zoomScale。

我能提供的唯一假设是它可能与Core Graphics和UIKit的不同默认坐标系有关,因为在那些坐标系中,x轴以相同的方式起作用,而y轴相反的功能。也许不知怎的,这在前面提到的setTransform重写中变得混乱。

答案 1 :(得分:0)

在努力解决同样的问题后,我能够提出一个解决方法。 将此代码用于setTransform方法。

-(void)setTransform:(CGAffineTransform)transform
{
    CGAffineTransform constrainedTransform = CGAffineTransformIdentity;
    constrainedTransform.d = self.initialScale * transform.d;
    constrainedTransform.d = (constrainedTransform.d < MINIMUM_ZOOM_SCALE) ? MINIMUM_ZOOM_SCALE : constrainedTransform.d;
    
    [super setTransform:constrainedTransform];
}
                                                                          

在scrollViewWillBeginZooming委托方法中设置initialScale属性。

答案 2 :(得分:0)

这个答案很大程度上取决于starryVere的回答(竖起大拇指!)

这是斯威夫特的starryVere代码。它位于缩放的UIView子类中:

var initialScale: CGFloat = 1.0
override var transform: CGAffineTransform {
    set{
        //print("1 transform... \(newValue), frame=\(self.frame), bounds=\(self.bounds)")
        var constrainedTransform = CGAffineTransformIdentity
        constrainedTransform.d = self.initialScale * newValue.d // vertical zoom
        //constrainedTransform.a = newValue.a // horizontal zoom
        super.transform = constrainedTransform
        //print("2 transform... \(constrainedTransform), frame=\(self.frame), bounds=\(self.bounds)")
    }
    get{
        return super.transform
    }
}

注释掉的打印件非常有助于理解转换过程中边界和边框会发生什么。

现在达到规模问题:

包含UIScrollViewDelegate的方法scrollViewDidEndZooming具有参数比例。根据我的测试,这个参数比例包含值zoomedView.transform.a,它是我们使用CGAffineTransformIdentity设置为1.0的水平比例因子。所以规模总是1.0。

修复很简单:

func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
    let myScale = zoomView.transform.d

}

使用myScale就像在水平缩放的情况下使用比例一样。

答案 3 :(得分:-2)

如果您提供您正在尝试的示例代码会更有帮助,但我会给您一些尝试。实际上你必须使内容大小宽度等于“320”,即等于iPhone的屏幕尺寸。

scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 45,320,480)];   
scrollView.contentSize = CGSizeMake(320,1000);
scrollView.showsVerticalScrollIndicator = YES;

MonoTouch版本如下:

scrollView = new UIScrollView (new RectangleF (0, 45, 320, 480)) {
    ContentSize = new SizeF (320, 1000),
    ShowVerticalScrollIndicator = true
};

希望它有帮助.. :) 是的,如果有帮助,别忘了接受答案:D