简体   繁体   English

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

[英]bounds and frames: how do I display part of an UIImage

My goal is simple; 我的目标很简单; I want to create a program that displays an UIImage, and when swiped from bottom to top, displays another UIImage. 我想创建一个显示UIImage的程序,并在从下往上滑动时显示另一个UIImage。 The images here could be a happy face/sad face. 此处的图像可能是笑脸/悲伤脸。 The sad face should be the starting point, the happy face the end point. 悲伤的脸应该作为起点,幸福的脸应该作为终点。 When swiping your finger the part below the finger should be showing the happy face. 滑动手指时,手指下方的部分应露出笑脸。

So far I tried solving this with the frame and bounds properties of the UIImageview I used for the happy face image. 到目前为止,我尝试使用用于笑脸图像的UIImageview的frame和bounds属性来解决此问题。

What this piece of code does is wrong, because the transition starts in the center of the screen and not the bottom. 该代码段的操作是错误的,因为过渡是从屏幕的中心而不是底部开始的。 Notice that the origin of both frame and bounds are at 0,0... 请注意,框架和边界的原点均为0,0 ...

I have read numerous pages about frames and bounds, but I don't get it. 我已经阅读了无数关于框架和边界的页面,但我不明白。 Any help is appreciated! 任何帮助表示赞赏!

The loadimages is called only once. 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);
}

The UIImages and UIImageViews are properly disposed of in the dealloc function. UIImages和UIImageViews在dealloc函数中已正确处理。

Indeed, you seem to be confused about frames and bounds. 确实,您似乎对框架和界限感到困惑。 In fact, they are easy. 实际上,它们很容易。 Always remember that any view has its own coordinate system. 永远记住,任何视图都有其自己的坐标系。 The frame, center and transform properties are expressed in superview's coordinates, while the bounds is expressed in the view's own coordinate system. 框架,中心和变换属性以超级视图的坐标表示,而界限则以视图自己的坐标系表示。 If a view doesn't have a superview (not installed into a view hierarchy yet), it still has a frame. 如果视图没有超级视图(尚未安装到视图层次结构中),则它仍具有框架。 In iOS the frame property is calculated from the view's bounds, center and transform. 在iOS中,frame属性是根据视图的边界,中心和变换来计算的。 You may ask what the hell frame and center mean when there's no superview. 您可能会问,当没有超级视图时,地狱的框架和中心意味着什么。 They are used when you add the view to another view, allowing to position the view before it's actually visible. 当您将视图添加到另一个视图时使用它们,从而可以在视图实际可见之前对其进行定位。

The most common example when a view's bounds differ from its frame is when it is not in the upper left corner of its superview: its bounds.origin may be CGPointZero, while its frame.origin is not. 当视图的边界与其框架不同时,最常见的示例是它不在其父视图的左上角:其bounds.origin可以是CGPointZero,而其frame.origin则不是。 Another classic example is UIScrollView, which frequently modifies its bounds.origin to make subviews scroll (in fact, modifying the origin of the coordinate system automatically moves every subview without affecting their frames), while its own frame is constant. 另一个经典示例是UIScrollView,它经常修改其bounds.origin以使子视图滚动(实际上,修改坐标系的原点会自动移动每个子视图而不影响其框架),而其自身的框架是恒定的。

Back to your code. 回到您的代码。 First of all, when you already have images to display in image views, it makes sense to init the views with their images: 首先,当您已经有要在图像视图中显示的图像时,用它们的图像初始化视图是有意义的:

UIImageView *face1view = [[UIImageView alloc] initWithImage: sadface];

That helps the image view to immediately size itself properly. 这有助于图像视图立即正确调整自身大小。 It is not recommended to init views with -init because that might skip some important code in their designated initializer, -initWithFrame: . 不建议使用-init初始化视图,因为这可能会跳过其指定的初始化程序-initWithFrame:一些重要代码。

Since you add face1view to self.view, you should really use its bounds rather than its frame: 由于将face1view添加到self.view中,因此您应该真正使用其边界而不是其框架:

face1view.frame = self.view.bounds;

Same goes for the happier face. 快乐的脸也一样。 Then in -touchesMoved:… you should either change face2view's frame to move it inside self.view or (if self.view does not contain any other subviews besides faces) modify self.view's bounds to move both faces inside it together. 然后在-touchesMoved:…您应该更改face2view的框架以将其移动到self.view内,或者(如果self.view除了人脸之外不包含任何其他子视图)修改self.view的边界以将其内的两个人脸一起移动。 Instead, you do something weird like vertically stretching the happy face inside face2view. 取而代之的是,您做了一些奇怪的事情,例如在face2view中垂直拉伸笑脸。 If you want the happy face to slide from the bottom of self.view, you should initially set its frame like this (not visible initially): 如果希望笑脸从self.view的底部滑动,则应首先将其框架设置如下(最初不可见):

face2view.frame = CGRectOffset(face2view.frame, 0, CGRectGetHeight(self.view.bounds));

If you choose to swap faces by changing image views' frames (contrasted with changing self.view's bounds ), I guess you might want to change both the views' frame origins, so that the sad face slides up out and the happy face slides up in. Alternatively, if you want the happy face to cover the sad one: 如果您选择通过更改图像视图的框架(与更改self.view的边界相反)来交换面部,我想您可能想同时更改两个视图的框架原点,以使悲伤的脸滑上去,而快乐的脸滑上来或者,如果您希望笑脸掩盖悲伤的脸,请执行以下操作:

face2view.frame = face1view.frame;

Your problem seems to have something to do with the face2view.bounds in touchesMoved. 您的问题似乎与touchesMoved中的face2view.bounds有关。 You are setting the bounds of this view to the rect, x:0, y:0, width:320, height:480 - y 您正在将此视图的边界设置为rect,x:0,y:0,宽度:320,高度:480-y

x = 0 == left on the x axis x = 0 ==留在x轴上

y = 0 == top on the y axis y = 0 == y轴顶部

So you are putting this image frame at the upper left corner, and making it fill the whole view. 因此,您要将这个图像框放在左上角,并使其充满整个视图。 That's not what you want. 那不是你想要的。 The image simply becomes centered in this imageView. 图像只是在此imageView中居中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM