gpt4 book ai didi

ios - 替换 UIView 时假的推送和弹出动画

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:15:57 31 4
gpt4 key购买 nike

出于某些原因,我必须使用 addSubviewaddChildViewController 来替换 View 而不是推送/弹出 View Controller 。问题是我想在更改 UIViewController(推送/弹出)时完全伪造动画。这是我的尝试:

RootViewController.m

// switch controller view
currentController = nextViewController;

[self addChildViewController:currentController];
[self.view addSubview:currentController.view];

// pop - move down
[currentController.view setFrame:CGRectMake(self.view.frame.size.width, 0, currentController.view.frame.size.width, currentController.view.frame.size.height)];

[UIView animateWithDuration:0.5
animations:^{
[currentController.view setFrame:CGRectMake(self.view.frame.size.width, self.view.frame.size.height, currentController.view.frame.size.width, currentController.view.frame.size.height)];
[self addConstrainForView];
}];


//Push - move up
[currentController.view setFrame:CGRectMake(0, self.view.frame.size.height, currentController.view.frame.size.width, currentController.view.frame.size.height)];
[UIView animateWithDuration:0.5
animations:^{
[currentController.view setFrame:CGRectMake(0, 0, currentController.view.frame.size.width, currentController.view.frame.size.height)];
[self addConstrainForView];
}];

此代码不作为方面工作,因为下一个 Controller 从底部移动到顶部(推),并且当它移动时,它后面有一个空白背景(根 Controller 的背景).

所以我需要正确的方法来伪造推送和弹出动画(上拉和下拉)。
如有任何帮助,我们将不胜感激。

最佳答案

我在一个应用程序中使用了这个效果。我想要(并且拥有)嵌入到 iPad 应用程序边缘的 iPhone 系列选择屏幕的外观。因此,用户按下列表中的一个按钮,然后屏幕转换(看起来像 UIViewController 前进)到更多选项,尽管它们都在边缘的窗口中(相关内容会在右侧弹出)。这是我使用的代码:

- (void)advanceLevel
{
UIImageView *screenShot = [self getTableScreenShot];
[self.tableView.superview addSubview:screenShot];

// Put screen shot over the whole thing with mask for iPhone style animation
TableViewMask *mask =
[[TableViewMask alloc] initWithFrame:CGRectMake(0, 0, 1024, 768) withImage:[Util TakeScreenshot]];
[self.tableView.superview addSubview:mask];

tableLevel++;
[self updateData];

[UIView animateWithDuration:.6 animations:^
{
screenShot.frame =
CGRectMake(self.tableView.frame.origin.x-self.tableView.frame.size.width, self.tableView.frame.origin.y,
self.tableView.frame.size.width, self.tableView.frame.size.height);
controller.toolbar.backButton.alpha = (tableLevel>1?1:0);
}
completion:^(BOOL finished)
{
[screenShot removeFromSuperview];
[mask removeFromSuperview];
[self updateUI];
}];
}

- (void)goBackLevel
{
if(tableLevel==1){ return; }

if(tableLevel==3 && isEditing==YES)
{
// Skip this screen if coming from higher screens
tableLevel--;
}

UIImageView *screenShot = [self getTableScreenShot];
[self.tableView.superview addSubview:screenShot];

// Put screen shot over the whole thing with mask for iPhone style animation
TableViewMask *mask = [[TableViewMask alloc] initWithFrame:CGRectMake(0, 0, 1024, 768) withImage:[Util TakeScreenshot]];
[self.tableView.superview addSubview:mask];

tableLevel--;
[self updateData];

[UIView animateWithDuration:.6 animations:^
{
screenShot.frame =
CGRectMake(self.tableView.frame.origin.x+self.tableView.frame.size.width, self.tableView.frame.origin.y,
self.tableView.frame.size.width, self.tableView.frame.size.height);
controller.toolbar.backButton.alpha = (tableLevel>1?1:0);
}
completion:^(BOOL finished)
{
[screenShot removeFromSuperview];
[mask removeFromSuperview];
[self updateUI];
}];
}

...这是截屏者:

+ (UIImage *)TakeScreenshot
{
CGSize imageSize = [[UIScreen mainScreen] bounds].size;

UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);

CGContextRef context = UIGraphicsGetCurrentContext();

// Iterate over every window from back to front
for (UIWindow *window in [[UIApplication sharedApplication] windows])
{
if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen])
{
// -renderInContext: renders in the coordinate space of the layer,
// so we must first apply the layer's geometry to the graphics context
CGContextSaveGState(context);
// Center the context around the window's anchor point
CGContextTranslateCTM(context, [window center].x, [window center].y);
// Apply the window's transform about the anchor point
CGContextConcatCTM(context, [window transform]);
// Offset by the portion of the bounds left of and above the anchor point
CGContextTranslateCTM(context,
-[window bounds].size.width * [[window layer] anchorPoint].x,
-[window bounds].size.height * [[window layer] anchorPoint].y);

// Render the layer hierarchy to the current context
[[window layer] renderInContext:context];

// Restore the context
CGContextRestoreGState(context);
}
}

// Retrieve the screenshot image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return image;
}

.. 最后是 TableViewMask:

@implementation TableViewMask

UIImage *screenShotImage;
- (instancetype)initWithFrame:(CGRect)frame withImage:(UIImage *)_screenShotImage
{
self = [super initWithFrame:frame];
if(self)
{
self.backgroundColor = [UIColor clearColor];

screenShotImage = _screenShotImage;

[self setNeedsDisplay];
}
return self;
}

- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();

[screenShotImage drawInRect:rect];

CGRect intersection = CGRectIntersection( CGRectMake(10.2, 130, 299.6, 600), rect );
if( CGRectIntersectsRect( intersection, rect ) )
{
CGContextFillRect(context, CGRectMake(10, 130, 300, 600));
CGContextClearRect(context, intersection);
CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
CGContextFillRect( context, intersection);
}
}

@end

我留下了一些我独有的东西,因为你可能需要类似的电话。例如 [self updateData] 会考虑系统状态来更新模型并设置任何其他基于状态的调用。当屏幕应该被跳过时也有一个异常(exception)我已经留下了。你可以安全地删除那些,尽管你可能需要类似的变体(因为你并没有真正改变 UIViewController 的)。

对此我唯一要注意的是,除非你有像我这样的极端情况——在 iPad 或类似的东西上的弹出 View 中模仿 iPhone——最好只使用真正的 UIVewController。

关于ios - 替换 UIView 时假的推送和弹出动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29349172/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com