【问题标题】:How to decrease the width of a frame of an UIImage gradually without distorting it?如何在不扭曲 UIImage 的情况下逐渐减小框架的宽度?
【发布时间】:2011-08-11 11:29:09
【问题描述】:

我认为这是一个非常基本的问题,但我正在努力解决这个问题。

我有一个屏幕截图(UIImage),我将其放入 UIView(在下面的示例中称为 screenShotView)。我想通过逐渐揭示这个screenShotView背后的东西来摆脱这个screenShotView。现在我的 screenShotView 向左挤压,但我希望它的 FRAME 越来越少,直到不再看到 screenShotView(没有挤压)。

这是我的代码。如果我使用 UITextView(而不是 UIImage)进行相同的转换,它将完全按照我希望的方式工作(无需转换)。

也许我没有理解框架 UIImages 的概念?

 [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:10];

    [screenShotView setFrame:CGRectMake(0, 0, 0, 480)];

[UIView commitAnimations];

这就是它在动画中间的样子:

这就是我希望它在动画中间的样子:


这是根据 Codo 的建议更新的代码(见下文),结果我再也没有动画了。一旦按下按钮,就会弹出蓝屏。我想我在添加子视图时做错了——问题似乎是没有添加子视图,因此不会消失:

    -(IBAction)showNextText
{


    screenShotView = [[UIImageView alloc] initWithImage:[self screenshot]];

    [screenShotView setFrame:CGRectMake(0, 0, 320, 480)];
    [screenShotScrollView setFrame:CGRectMake(0, 0, 320, 480)];

    [self.view addSubview:screenShotScrollView];
    [screenShotScrollView addSubview:screenShotView];
    screenShotScrollView.scrollEnabled = NO;


    [self setUpNextText];
    [self removeOldText];

}

-(void)setUpNextText
{
    NSString* secondText = @"This is the second text shown if the user clicks next.";
    textView.text = secondText;
    textView.textColor = [UIColor redColor];
    textView.backgroundColor = [UIColor blueColor];
}

-(IBAction)removeOldText{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:5];

    [screenShotScrollView setFrame:CGRectMake(0,0,320,480)];

    [UIView commitAnimations];

}

【问题讨论】:

  • 您需要的过渡类似于旧的星球大战电影?两个屏幕的位置和大小不会改变,只是一个在某一行重叠,并随着时间的推移隐藏另一个。对吗?
  • @Nick Weaver:没错!我应该考虑星球大战的。它就像一条线或窗帘,您向左移动。屏幕不会移动——只是屏幕显示的内容会发生变化。上面的从 100% 到 0%,下面的从 0% 到 100%。
  • 我怀疑这种过渡是否可以轻松创建!不过我明天再看看。您应该考虑一些简单的 alpha 混合动画:看起来不错,并且可以在几分钟内创建。
  • @Nick Weaver:非常感谢。我知道 alpha 混合看起来不错,但是因为我想要翻页效果,所以我需要这种过渡。我按照 Codo 的建议使用 UIScrollView 进行了尝试,但到目前为止还没有运气。再次感谢您的帮助。
  • @n.evermind 你真的试过UIView transitionFromView ... 和 UIViewAnimationOptionTransitionFlipFromLeft 吗?还是 UIViewAnimationOptionTransitionCurlUp?看起来也不错:)

标签: iphone objective-c cocoa-touch uiimage


【解决方案1】:

不要为frame 设置动画,而是为center 设置动画。请参阅文档here

另外,如果您只需要兼容 iOS 4,请使用-animateWithDuration:animations:

[UIView animateWithDuration:10
                 animations:^{ screenShotView.center = CGPointMake(x, y) } ];

【讨论】:

  • 非常感谢,但我该怎么做呢? [screenShotView setCenter:CGRectMake(0, 0, 0, 480)]; ?
  • center 是一个只有两个坐标的CGPoint;使用CGPointMake(x, y)
  • 您还可以为框架的 x 部分设置动画并保持宽度和高度相同:例如 CGRectMake(320, 0, 320, 480)
  • @n.evermind 好吧,也许我误解了你。 “越来越少”是什么意思?
  • @fabian798:我更新了我的问题,用一张我希望它如何出现的图片。你建议把整个东西移到视线之外。
【解决方案2】:

我不确定我是否完全理解您希望您的视图如何消失。

如果它应该变得越来越透明,请使用以下代码(而不是 setFrame):

[screenShotView setAlpha: 0.0f];

如果它应该变得越来越小(但保持其中心),那么尝试:

[screenShotView setFrame:CGRectMake(screenShotView.frame.x, screenShotView.frame,y, 0, 0)];

【讨论】:

  • 感谢您的帮助,但我认为这并不是我真正需要的。我想我并没有很清楚地表达自己——我用一张图片更新了我的帖子,这张图片说明了我想要实现的目标。如果您能快速浏览一下,我将不胜感激。
【解决方案3】:

回答问题

实际上非常简单:我制作了一个示例应用程序来让星球大战(只是在这里调用它)过渡工作。为简单起见,我只称这两个视图为 firstView 和 secondView。显示 firstView (将是您的屏幕截图), secondView 将从左侧滑入。我在每个视图上都放了一个按钮来动画过渡,这与doTransition 很相似。重要的部分是设置视图属性clipsToBounds = YESautoresizesSubviews = NO 的滑动。而已。我会发布一些截图。

- (void)viewDidLoad 
{
    [super viewDidLoad];
    secondView.frame = CGRectMake(0, 0, 0, 480);
    secondView.clipsToBounds = YES;
    secondView.autoresizesSubviews = NO;

    [self.view addSubview:firstView];   
    [self.view addSubview:secondView];  
}

- (IBAction)doTransition
{
    [UIView animateWithDuration:1.0 
                     animations:^{
                         self.secondView.frame = CGRectMake(0, 
                                                            0, 
                                                            320, 
                                                            480);
                     }];
}

卷曲研究

我对翻页/卷曲效果做了一些研究。主要是这些都存在于 iOS 中,您可以毫不费力地创建 iBook 翻页效果,但它正在访问私有方法和类。我仍然鼓励任何人看看它,因为它可能有一天会被打开。

【讨论】:

  • 谢谢尼克,但我认为这并不是我真正想要做的(我的错,我应该让它更清楚一点)。 Codo 提出了如何 CLIP 截图的建议,但还是不行。
  • 更改了整个答案,这不是您问题的答案,但可能仍然很有趣。
  • 谢谢尼克,你真好。很多我可以看。 Hoha(上图)还提供了一些我需要测试的解决方案。
【解决方案4】:

我猜你必须把你的上视图放到一个UIScrollView中。然后将内容大小设置为与 UIScrollView 的大小相同并禁用滚动。

接下来您在 UIScrollView 上制作原始动画 (setFrame)。

基本上,然后您使用 UIScrollView 为内部视图引入一个单独的坐标系。当外层视图(滚动视图)变小时,不会扭曲内层视图,而是剪掉它。

【讨论】:

  • 听起来不错,但我尝试实现这一点(参见上面的代码),但它根本不起作用。我想我在尝试添加所有这些不同的视图时做错了。任何建议将不胜感激。谢谢!
  • 您能否更具体地了解“根本行不通”的含义?我可以在您的代码中看到两个潜在的问题:根据屏幕截图,视图的高度不应该是 480 像素,而是大约 200 像素。您应该设置滚动视图的 contentSize 属性。
  • 对不起,我的意思是根本没有动画(没有挤压)并且蓝色视图(最初在背景中)只是出现而另一个白色视图(最初在前面)只是消失了.关于像素高度,我将它们设置为 200,以便我可以看到按钮。关于 contentSize 属性 - 我如何设置它以及为什么这是必要的?很抱歉让您如此痛苦,感谢您的耐心等待。
【解决方案5】:
CGRect fillRect = self.view.bounds;

leftImageView.clipsToBounds = YES;
leftImageView.contentMode = UIViewContentModeTopLeft;
leftImageView.frame = fillRect;

rightImageView.clipsToBounds = YES;
rightImageView.contentMode = UIViewContentModeTopRight;
rightImageView.frame = CGRectMake(fillRect.size.width, 0, 0, fillRect.size.height);

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:3];

leftImageView.frame = CGRectMake(0, 0, 0, fillRect.size.height);
rightImageView.frame = fillRect;

[UIView commitAnimations];

【讨论】:

    猜你喜欢
    • 2020-06-02
    • 2018-09-25
    • 2016-07-31
    • 1970-01-01
    • 2015-09-01
    • 2013-12-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    相关资源
    最近更新 更多