Drawer effect function implementation, drawer effect implementation
Drawer effect function implementation 1. h file @ interfaceHMDrawViewController: UIViewController
@ Property (nonatomic, weak, readonly) UIView * mainView;
@ Property (nonatomic, weak, readonly) UIView * leftView;
@ Property (nonatomic, weak, readonly) UIView * rightView;
@ End
Ii.. m file @ interfaceHMDrawViewController ()
@ Property (nonatomic, assign) BOOL isDraging;
@ End
@ ImplementationHMDrawViewController
-(Void) viewDidLoad
{
// UIViewController
[SuperviewDidLoad];
// Do any additional setup after loading the view.
// 1. Add a child Control
[SelfaddChildView];
# Warning Step 3: Observe the frame change of _ mainView
// 2. Listen
/**
* Add an observer to _ mainView
*
* KeyPath: listens to the frame attribute.
*
* Options: Listen for changes to New Values
*/
[_ MainViewaddObserver: selfforKeyPath: @ "frame" options: NSKeyValueObservingOptionNewcontext: nil];
}
// When the frame attribute of _ mainView is changed, it is called
-(Void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary *) change context :( void *) context
{
NSLog (@ "% @", NSStringFromCGRect (_ mainView. frame ));
If (_ mainView. frame. origin. x <0) {// move to the left
// Display the right side
_ RightView. hidden = NO;
// Hide the left
_ LeftView. hidden = YES;
} Elseif (_ mainView. frame. origin. x> 0) {// move to the right
// Display the left
_ RightView. hidden = YES;
// Hide the right
_ LeftView. hidden = NO;
}
}
# Warning Step 1
-(Void) addChildView
{
// Left
UIView * leftView = [[UIViewalloc] initWithFrame: self. view. bounds];
LeftView. backgroundColor = [UIColorgreenColor];
[Self. viewaddSubview: leftView];
_ LeftView = leftView;
// Right
UIView * rightView = [[UIViewalloc] initWithFrame: self. view. bounds];
RightView. backgroundColor = [UIColorblueColor];
[Self. viewaddSubview: rightView];
_ RightView = rightView;
// MainView
UIView * mainView = [[UIViewalloc] initWithFrame: self. view. bounds];
MainView. backgroundColor = [UIColorredColor];
[Self. viewaddSubview: mainView];
_ MainView = mainView;
}
# Step 2 of warning
-(Void) touchesMoved :( NSSet *) touches withEvent :( UIEvent *) event
{
// Obtain the UITouch object
UITouch * touch = [touchesanyObject];
// Obtain the current vertex
CGPoint currentPoint = [touchlocationInView: self. view];
// Obtain the previous Vertex
CGPoint prePoint = [touchpreviuslocationinview: self. view];
// Offset of the x axis: the offset of x when the finger moves a little.
CGFloat offsetX = currentPoint. x-prePoint. x;
// Set the frame of the current main view
_ MainView. frame = [selfgetCurrentFrameWithOffsetX: offsetX];
_ IsDraging = YES;
}
# Step 4 of warning
# Define HMMaxY 60
// When the finger offset is a little bit, the frame of the current main view is calculated based on the offset of the X axis.
-(CGRect) getCurrentFrameWithOffsetX :( CGFloat) offsetX
{
CGFloat screenW = [UIScreenmainScreen]. bounds. size. width;
CGFloat screenH = [UIScreenmainScreen]. bounds. size. height;
// Obtain the y-axis offset. The value of the Y-axis offset varies with each point the finger moves.
CGFloat offsetY = offsetX * HMMaxY/screenW;
CGFloat scale = (screenH-2 * offsetY)/screenH;
If (_ mainView. frame. origin. x <0) {// move to the left
Scale = (screenH + 2 * offsetY)/screenH;
}
// Obtain the previous frame
CGRect frame = _ mainView. frame;
Frame. origin. x + = offsetX;
Frame. size. height = frame. size. height * scale;
Frame. size. width = frame. size. width * scale;
Frame. origin. y = (screenH-frame. size. height) * 0.5;
Return frame;
}
Note: The fixed height of the drawer effect is hard to write. You can define a macro to facilitate later maintenance.
Algorithm: offsetY = offsetX * 60/320
Scale = currentH/screenH
CurrentH = screenH-2 * offsetY
X = frame. origin. x + offsetX
H = frame. size. height * scale
W = frame. size. weight * scale
Y = (screenH-h) * 0.5
# Define HMRTarget250
# Define HMLTarget-220
/*
_ MainView. frame. origin. x> screenW * 0.5 go to the right
CGRectGetMaxX (_ mainView. frame) <screenW * 0.5 go to left-220
*/
// Locate
-(Void) touchesEnded :( NSSet *) touches withEvent :( UIEvent *) event
{
// Reset
If (_ isDraging = NO & _ mainView. frame. origin. x! = 0 ){
[UIViewanimateWithDuration: 0.25 animations: ^ {
_ MainView. frame = self. view. bounds;
}];
}
CGFloat screenW = [UIScreenmainScreen]. bounds. size. width;
CGFloat target = 0;
If (_ mainView. frame. origin. x> screenW * 0.5) {// locate to the right
Target = HMRTarget;
} Elseif (CGRectGetMaxX (_ mainView. frame) <screenW * 0.5) {// locate to the left
Target = HMLTarget;
}
[UIViewanimateWithDuration: 0.25 animations: ^ {
If (target) {// locate the target on the left or right
// Obtain the x-axis offset
CGFloat offsetX = target-_ mainView. frame. origin. x;
// Set the frame of the current main view
_ MainView. frame = [selfgetCurrentFrameWithOffsetX: offsetX];
} Else {// restore
_ MainView. frame = self. view. bounds;
}
}];
_ IsDraging = NO;
}
Note: When resetting, You need to define a member variable record.
@ End
Note: Knowledge Point 1: KVO observer mode. Add an observer to _ mainView. KeyPath: listens to the frame attribute. options: listens for changes to new values, the following method is called when the value of the frame attribute changes. -(Void) observeValueForKeyPath :( NSString *) keyPath ofObject :( id) object change :( NSDictionary *) change context :( void *) context; Knowledge Point 2: drawer effect algorithm.