Reputation: 2412
I have a custom View banner that has expand/collapse animation, something like described here iphone: expand and collapse a UIView programmatically .
What I want that when I integrate that view to any my existing View Controllers, when it get expanding to push down existing views. Now it's just overlaps.
How can I accomplish that in iOS? In Android I have done it using Visibility.Gone , but here I wasn't able to find anything like that. Banner can be in any view hierarchy , directly child of main view, but when it's expands I want all views move down, to have effect that it pushes down everything when expands.
Here the link for Android approach using Visibility.Gone Android: Expand/collapse animation
Upvotes: 2
Views: 3665
Reputation: 31745
You can get your result by manipulating the frame properties of the banner view and it's siblings in the banner's view hierarchy. All of this can be contained inside the banner view object. The frame
property is animatable.
Make a BannerView as a subclass of UIView. Add some methods to it's public @interface
:
- (void) collapse;
- (void) expand;
- (void) toggle;
You will want a couple of properties for the banner's expanded and collapsed frames:
@property (nonatomic, assign) CGRect expandedFrame;
@property (nonatomic, assign) CGRect collapsedFrame;
These can go in the (public) @interface or in a (private) category extension. Set them during the BannerView's initialisation:
//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;
}
Whenever you expand or collapse your bannerView, it can iterate through it's sibling views using the iteration form
for (UIView* view in self.superview.subviews) {}
moving them up or down accordingly by setting their respective frame
properties. To raise and lower frames, add or subtract the height of the 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;
}
Putting those pieces together, you can make collapse and expand animation methods which move sibling views into the correct postion by setting their frames and then collapse/expand the banner view by setting it's 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;
}];
}
…and a toggle method to move between the two states
- (void) toggle {
if (CGRectEqualToRect(self.frame, self.collapsedFrame))
[self expand];
else [self collapseBanner];
}
Upvotes: 4