相应地移动视图uiview折叠/展开动画

时间:2013-08-23 07:47:41

标签: ios objective-c uikit

我有一个自定义视图横幅,其中包含展开/折叠动画,类似于此处所述iphone: expand and collapse a UIView programmatically

当我将该视图集成到任何现有的View控制器时,当它扩展为压低现有视图时,我想要的是什么。现在它只是重叠。

如何在iOS中实现这一目标?在Android中我使用Visibility.Gone完成了它,但在这里我无法找到类似的东西。横幅可以在任何视图层次结构中,直接是主视图的子视图,但是当它扩展时,我希望所有视图向下移动,以便在扩展时推送所有视图。

此处使用Visibility.Gone Android: Expand/collapse animation

的Android方法链接

1 个答案:

答案 0 :(得分:4)

您可以通过操纵横幅视图的框架属性及横幅视图层次结构中的兄弟节点来获取结果。所有这些都可以包含在横幅视图对象中。 frame属性是可动画的。

将BannerView作为UIView的子类。将一些方法添加到公共@interface

    - (void) collapse;
    - (void) expand;
    - (void) toggle;

您需要为横幅的展开和折叠框架添加几个属性:

@property (nonatomic, assign) CGRect expandedFrame;
@property (nonatomic, assign) CGRect collapsedFrame;

这些可以放在(公共)@interface或(私有)类别扩展中。在BannerView初始化期间设置它们:

    //initialising in code
    - (id)initWithFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            [self initialiseFrames:frame];
        }
        return self;
    }

    //initialising from XIB/Storyboard
    - (void)awakeFromNib {
        [self initialiseFrames:self.frame];
    }

    - (void)initialiseFrames:(CGRect)frame {
        self.expandedFrame = frame;
        frame.size.height = 0;
        self.collapsedFrame = frame;
    }

每当您展开或折叠bannerView时,它都可以使用迭代表格迭代它的兄弟视图

for (UIView* view in self.superview.subviews) {}

通过设置各自的frame属性来相应地向上或向下移动它们。要升高和降低帧数,请添加或减去bannerView ...

的高度
- (CGRect)lowerFrame:(CGRect)frame {
    frame.origin.y += CGRectGetHeight(self.expandedFrame);
    return frame;
}

- (CGRect)raiseFrame:(CGRect)frame {
    frame.origin.y -= CGRectGetHeight(self.expandedFrame);
    return frame;
}

将这些部分放在一起,您可以制作折叠和展开动画方法,通过设置框架将兄弟视图移动到正确的位置,然后通过设置它的框架来折叠/展开横幅视图:

- (void) collapse {
    if (CGRectEqualToRect(self.frame, self.collapsedFrame)) return;
    [UIView animateWithDuration:0.5 animations:^{
        for (UIView* view in self.superview.subviews) {
            if (CGRectGetMinY(view.frame) > CGRectGetMaxY(self.frame))
                view.frame = [self raiseFrame:view.frame];
        }
        self.frame = self.collapsedFrame;
    }];

}

- (void) expand {
    if (CGRectEqualToRect(self.frame, self.expandedFrame)) return;
    [UIView animateWithDuration:0.5 animations:^{
        for (UIView* view in self.superview.subviews) {
            if (CGRectGetMinY(view.frame) > CGRectGetMaxY(self.frame))
                view.frame = [self lowerFrame:view.frame];
        }
        self.frame = self.expandedFrame;
    }];

}

...以及在两种状态之间移动的切换方法

- (void) toggle {
    if (CGRectEqualToRect(self.frame, self.collapsedFrame))
        [self expand];
    else [self collapseBanner];
}