在 ViewController 中显示动画视图

Posted

技术标签:

【中文标题】在 ViewController 中显示动画视图【英文标题】:Display animating view within ViewController 【发布时间】:2013-12-19 08:14:11 【问题描述】:

已编辑:

我为我的视图创建了一个幻灯片菜单,它可以按我的意愿工作,这是我使用的原始指南。

http://www.youtube.com/watch?v=79ZQDzzOHLk

我的目标是在课堂上编写一次,让它在我决定调用它的任何视图控制器上工作。

感谢@harsh.prasad 和一些额外的研究,除了将按钮链接到它之外,我已经设法让它工作到我想要的地步。

所以更新这个问题,希望它可以帮助别人。

这就是我所做的:

我创建了一个 UIView 类并将其命名为 MenuOne。

MenuOne.h

#import <UIKit/UIKit.h>

@interface TFMenuOne : UIView 
    // Pop Up Menu

    IBOutlet UIScrollView *scrollView;
    IBOutlet UIButton *openMenu;
    int draw1;
    IBOutlet UIButton *backButton;


// Pop Up Menu
- (IBAction)openMenu_clicked:(id)sender;

// Reset draw1 to 0
- (void) resetView: (id) sender;

@property (retain, nonatomic) IBOutlet UIScrollView *scrollView;

@end

MenuOne.m

#import "TFMenuOne.h"

@implementation TFMenuOne
@synthesize scrollView;

- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 

        draw1 = 0;

        scrollView = [[UIScrollView alloc] init];
        [scrollView setBackgroundColor:[UIColor whiteColor]];
        [scrollView setFrame:CGRectMake(0, 315, 568, 5)];
        [scrollView setContentSize:CGSizeMake(568, 5)];


        backButton = [[UIButton alloc] init];
        [backButton setBackgroundColor:[UIColor greenColor]];
        backButton.frame = CGRectMake(224, 350, 120, 30);

        openMenu = [[UIButton alloc] init];
        [openMenu setBackgroundImage:[UIImage imageNamed:@"menu-button-@2.png"]
                            forState:UIControlStateNormal];
        openMenu.adjustsImageWhenHighlighted = NO;
        [openMenu addTarget:self
                     action:@selector(openMenu_clicked:)
           forControlEvents:UIControlEventTouchUpInside];
        openMenu.frame = CGRectMake(256, 269, 64, 46);


        [self addSubview:scrollView];
        [self addSubview:backButton];
        [self addSubview:openMenu];

     
    return self; 


// Allow for touch even through transparent View class
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
    for (UIView *view in self.subviews) 
        if (!view.hidden && view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event])
            return YES;
    
    return NO;


- (void) resetView: (id) sender 
    draw1 = 1;
    [self openMenu_clicked:sender];


- (IBAction)openMenu_clicked:(id)sender 
    if (draw1 == 0) 

        draw1 = 1;

        [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
            scrollView.frame = CGRectMake(0, 260, 568, 60);
         completion:^(BOOL finished) 

        ];

        [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
            openMenu.frame = CGRectMake(256, 214, 64, 46);
         completion:^(BOOL finished) 

        ];

        [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
            backButton.frame = CGRectMake(224, 275, 120, 30);
         completion:^(BOOL finished) 

        ];


     else 

        draw1 = 0;

        [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
            scrollView.frame = CGRectMake(0, 315, 568, 5);
         completion:^(BOOL finished) 

        ];

        [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
            openMenu.frame = CGRectMake(256, 269, 64, 46);
         completion:^(BOOL finished) 

        ];

        [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
            backButton.frame = CGRectMake(224, 350, 120, 30);
         completion:^(BOOL finished) 

        ];

    



/* 
 // Only override drawRect: if you perform custom drawing. 
 // An empty implementation adversely affects performance during animation. 
 - (void)drawRect:(CGRect)rect 
  
 // Drawing code 
  
 */ 

@end

经过大量的试验和错误,为了让这个 UIView 类出现在多个 ViewControllers 上,我在视图控制器的 m 文件中这样调用视图。我遇到的障碍是菜单会打开,但是当我离开视图控制器转到另一个视图控制器时,菜单将处于我离开时的状态,它不会重置回关闭状态。下面的代码再次感谢@harsh.prasad。我还设法让菜单进入动画。

@interface TFMapViewController ()

    TFMenuOne *menuView;


@end

@implementation TFMapViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        // Custom initialization
        [menuView resetView:nil];
    
    return self;


- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view.
    menuView = [[TFMenuOne alloc] initWithFrame:CGRectMake(0, 51, 568, 320)];
    [self.view addSubview:menuView];



- (void) viewDidAppear:(BOOL)animated


    [UIView animateWithDuration:0.5 delay:0.5 options:UIViewAnimationOptionBeginFromCurrentState animations:^
        menuView.frame = CGRectMake(0, 0, 568, 320);
     completion:^(BOOL finished) 

    ];




- (void) viewDidDisappear:(BOOL)animated

    [menuView resetView:nil];
    [UIView animateWithDuration:0.0 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
        menuView.frame = CGRectMake(0, 51, 568, 320);
     completion:^(BOOL finished) 

    ];


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


// Allows for Exit button to work
- (IBAction)returned:(UIStoryboardSegue *)segue 




@end

【问题讨论】:

你一定要看看MFSideMenu 感谢 Janak,但这不是我想要的。我查看了幻灯片菜单,但它给出了与我想要的不同的效果 - 我希望我的菜单出现在视图控制器上而不是后面,我希望能够在其上添加按钮和图像而不仅仅是文本菜单。我已经实现了我想要的,但想知道是否有一种有效的方法不必在每个视图控制器上重复相同的代码。还是谢谢。 【参考方案1】:

如果你想要那种功能,你可以使用 tabsController,否则在菜单视图中创建一个幻灯片类,然后你可以在所有视图中随意使用它。没有相同的代码被重写。

编辑: 假设您创建了一个类 CustomMenuView,它基本上创建了您的菜单视图。因此,现在您可以通过以下方式在要使用它的每个视图控制器中使用它:

CustomMenuView *menuView = [CustomMenuView alloc] initWithFrame:CGRectMake(0, 200, 320, 100);
menuView.<properties you want to pass> = <set properties here>;
[self.view addSubView:menuView];

这将使用自定义菜单设置视图,然后您可以处理此菜单中的操作。

【讨论】:

因此,如果我只为菜单创建一个类,我是否还要为它创建一个视图控制器,如果是这样,我如何将它调用到我希望它出现的每个视图控制器? 菜单的 UIView 类就足够了。只需在 initWithFrame 函数中处理视图。我认为这可以轻松解决您的问题。 好的,知道我将如何编码吗?我现在已经创建了这个类,它就坐在那里,但不知道如何将它编码到每个视图控制器中以使其工作。有什么想法吗? 我已经编辑了我的原始答案。您可以根据需要设置框架。这应该工作 嗨,harsh.prasad,我正在学习objective-c,非常感谢您为帮助我付出的时间和努力,但我认为您认为我比我知道的更多。我需要导入吗,如果需要,我应该导入什么?为什么我已经在菜单视图控制器中完成了设置属性?我只是收到错误。第一行说它正在等待],然后我收到错误消息,说 initWithFrame 没有可见的@interface。我曾尝试导入 m 和 h 文件并且都给出相同的错误 - 有什么想法吗? PS我把你的代码放在viewDidLoad中【参考方案2】:

1)这是一个创建菜单的旧教程 - http://www.raywenderlich.com/32054/how-to-create-a-slide-out-navigation-like-facebook-and-path/projectlayout

2)更好的方法是使用容器视图创建抽屉菜单。您可以从 WWDC 视频中了解有关容器视图的更多信息。

3)或者如果你懒得自己d,试试这个库http://cocoacontrols.com/platforms/ios/controls/jtrevealsidebar

附:不,您不必重复代码。

【讨论】:

【参考方案3】:

你可以试试这个,

首先查看原点 x = 0 y = 480(对于 iphone4),然后运行此代码。

CGRect theFrame = self.viewMenuShare.frame;
theFrame.origin = CGPointMake(0, 480);
self.viewMenuShare.frame = theFrame;
theFrame.origin = CGPointMake(0,480 - 187);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f];
self.viewMenuShare.frame = theFrame;
[UIView commitAnimations];

【讨论】:

以上是关于在 ViewController 中显示动画视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在视图控制器中为 xib 约束设置动画?

关闭一个视图控制器并显示另一个视图控制器

有办法在两个 viewController 之间共享 UI 元素吗?

CALayer 旋转动画不适用于呈现的 ViewController

swift 4 - segue 动画完成后如何在目标视图控制器中运行代码?

iOS:具有透明背景的模态 ViewController