边界和框架:如何显示 UIImage 的一部分

4
我的目标很简单:我想创建一个程序,显示一个UIImage,当从底部向上滑动时,显示另一个UIImage。这里的图像可以是快乐的面孔/悲伤的面孔。悲伤的面孔应该是起点,快乐的面孔是终点。当用手指滑动时,手指下面的部分应该显示快乐的面孔。
到目前为止,我尝试使用UIImageview的frame和bounds属性来解决这个问题。
这段代码做的不对,因为过渡效果始于屏幕中心而不是底部。请注意,框架和边界的原点都在0,0处......
我已经阅读了许多关于框架和边界的页面,但我还是不理解。任何帮助都将不胜感激! loadimages仅被调用一次。
- (void)loadImages {
    sadface = [UIImage imageNamed:@"face-sad.jpg"];
    happyface = [UIImage imageNamed:@"face-happy.jpg"];
    UIImageView *face1view = [[UIImageView alloc]init];
    face1view.image = sadface;
    [self.view addSubview:face1view];

    CGRect frame;
    CGRect contentRect = self.view.frame;
    frame = CGRectMake(0, 0, contentRect.size.width, contentRect.size.height);
    face1view.frame = frame;
    face2view = [[UIImageView alloc]init];
    face2view.layer.masksToBounds = YES;
    face2view.contentMode = UIViewContentModeScaleAspectFill;
    face2view.image = happyface;
    [self.view addSubview:face2view];
    frame = CGRectMake(startpoint.x, 0, contentRect.size.width, contentRect.size.height);
    face2view.frame = frame;
    face2view.clipsToBounds = YES;
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint movepoint = [[touches anyObject] locationInView: self.view];
    NSLog(@"movepoint: %f %f", movepoint.x, movepoint.y);
    face2view.bounds = CGRectMake(0, 0, 320, 480 - movepoint.y);
}

在dealloc函数中,正确地释放了UIImages和UIImageViews。

2个回答

2
事实上,您似乎对框架和边界感到困惑。但它们很简单。请始终记住,任何视图都有自己的坐标系。frame、center和transform属性是以父视图的坐标为基准来表达的,而bounds则是以视图自身的坐标系来表达的。如果一个视图没有父视图(尚未安装到视图层次结构中),它仍然有一个frame。在iOS中,frame属性是从视图的bounds、center和transform计算出来的。您可能会问:当没有父视图时,frame和center到底意味着什么。它们用于将视图添加到另一个视图中,允许在实际可见之前定位视图。
最常见的例子是,当一个视图不在其父视图的左上角时,它的bounds与frame不同:它的bounds.origin可能是CGPointZero,而其frame.origin则不是。另一个经典的例子是UIScrollView,它经常修改其bounds.origin以使子视图滚动(实际上,修改坐标系的原点会自动移动每个子视图,而不影响它们的frame),而其自身的frame是恒定的。
回到您的代码。首先,当您已经拥有要在图像视图中显示的图像时,使用这些图像初始化视图是有意义的:
UIImageView *face1view = [[UIImageView alloc] initWithImage: sadface];

这有助于图像视图立即正确地调整大小。不建议使用-init来初始化视图,因为这可能会跳过它们指定的初始化程序中的一些重要代码,比如-initWithFrame:

由于您将face1view添加到self.view中,因此应该真正使用其边界而不是其框架:

face1view.frame = self.view.bounds;

同样适用于更高兴的表情。在-touchesMoved:…中,您应该将face2view的frame更改为将其移动到self.view内部,或者(如果self.view除了表情之外没有其他子视图)修改self.view的bounds以将两个表情一起移动到其中。相反地,您会做一些奇怪的事情,比如在face2view内部垂直拉伸快乐的表情。如果您想让快乐的表情从self.view的底部滑动,则应最初设置其框架如下(初始时不可见):
face2view.frame = CGRectOffset(face2view.frame, 0, CGRectGetHeight(self.view.bounds));

如果您选择通过更改图像视图的框架来交换面孔(与更改self.view的边界相对),我猜您可能想要同时更改视图的框架原点,这样悲伤的脸就会向上滑出,而愉快的脸则会向上滑入。或者,如果您想让愉快的脸覆盖悲伤的脸:

face2view.frame = face1view.frame;

0

你的问题似乎与touchesMoved中的face2view.bounds有关。 你将该视图的边界设置为矩形,x:0,y:0,宽度:320,高度:480 - y

当 x = 0 时,在 x 轴上是最左侧

当 y = 0 时,在 y 轴上是最顶部

所以你将这个图像放置在左上角,并使其填充整个视图。这不是你想要的效果。图像只是在此imageView中居中显示。


我认为我需要将图像框放在左上角。这是因为图像必须重叠(它们是相同的图像,因此如果我将其放在其他任何地方,快乐的脸会相对于悲伤的脸移动)。有没有办法从底部开始显示快乐的脸? - Michel Boezerooij
我不确定我理解你的意思,你能用另一种方式描述一下吗? - Allyn
图片应该彼此叠放。因为这些图片大部分都是相同的,除了一个微笑的嘴巴和一个悲伤的嘴巴。当转换发生时,整个图像应该保持在一个位置上。看起来只有嘴巴从悲伤变成了快乐。为了实现这一点,两个图像都应该从0,0开始。这意味着两个图像都有一个从0,0到320,480的框架。 - Michel Boezerooij

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接