iOS Recipes - Matt Drance [10]
SlideInView/SlideInView.m
CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"position"];
basic.fromValue = [NSValue valueWithCGPoint:fromPos];
basic.toValue = [NSValue valueWithCGPoint:toPos];
self.layer.position = toPos;
[self.layer addAnimation:basic forKey:@"basic"];
If the bounce option is set to NO, we use the simpler CABasicAnimation on the layer to achieve our slide-into position.
SlideInView/SlideInView.m
popInTimer = [NSTimer scheduledTimerWithTimeInterval:timer
target:self
selector:@selector(popIn)
userInfo:nil
repeats:NO];
Because we want the notification to be able to remove itself, we add an NSTimer object that calls the popIn method after the selected time.
SlideInView/SlideInView.m
[UIView beginAnimations:@"slideIn" context:nil];
self.frame = CGRectOffset(self.frame, -adjustX, -adjustY);
[UIView commitAnimations];
To dismiss the view, we don’t need to worry about which animation style to use—we can use a UIView animation block to reposition the view offscreen. We simply use the negative value of the adjustment variables we calculated earlier to ensure we animate off the screen in the correct direction.
SlideInView/SlideInView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[popInTimer invalidate];
[self popIn];
}
A single touch to the SlideInView, which then triggers the touchesBegan:withEvent delegate method, is enough for us to cancel the timer and trigger the slide-back animation.
The MainViewController class shows the use of SlideInView objects from each of the four possible directions. The IBSlideIn instance was built in Interface Builder and shows how you can create more interesting, and possibly dynamic, notifications using multi-element views.
You can easily modify this technique to use different transition effects such as fades or flips or perhaps increase the visibility of the notification with additional animation in the view itself.
Recipe 4 Create Reusable Toggle Buttons
Problem
You want to create a custom button that can be toggled between an “on” and “off” state, and UISwitch doesn’t quite fit your design. You want this button to be reusable, without the need to write state management code in every view controller that uses it.
Solution
The UIButton class is extremely versatile, making it relatively easy to implement this feature with a small amount of customization. As a subclass of UIControl, UIButton supports multiple states including highlighted, enabled, and selected. We can set custom images, text, and text colors for all of these states. This flexibility gives us all we need to add toggle support to a standard UIButton.
A demonstration of our PRPToggleButton in its off, on, and highlighted (finger down) states
Figure 9. An image-based toggle button
* * *
Let’s take a look at what needs to be done. We need three button images: normal (or “off”), selected (or “on”), and a darker “pressed” mode. Figure 9, An image-based toggle button illustrates what these three states might look like. To make the process of supporting these states easier, and even automated, we’ll declare a subclass. This PRPToggleButton will take care of all the state and image management for us, so we don’t have to litter our controller code with image names and text colors every time a button is tapped. We can even set up the button in Interface Builder (IB), which allows the setting of per-state images, text, and colors.
The subclass declaration is very simple: it declares a boolean property to control whether the button automatically toggles itself when tapped, and it declares a convenience method for setting up and managing the various button state images.
ToggleButton/Classes/PRPToggleButton.h
@interface PRPToggleButton : UIButton {}
// Defaults to YES
@property (nonatomic, getter=isOn) BOOL on;
@property (nonatomic, getter=isAutotoggleEnabled) BOOL autotoggleEnabled;
+ (id)buttonWithOnImage:(UIImage *)onImage
offImage:(UIImage