SoFunction
Updated on 2025-04-10

How to implement the simple drawer effect of iOS

This article shares the specific code for iOS to realize simple drawer effect for your reference. The specific content is as follows

Implementation ideas and steps:

1. First prepare the view to slide

#warning Step 1- (void)addChildView
{
    // left
    UIView *leftView = [[UIView alloc] initWithFrame:];
     = [UIColor greenColor];
    [ addSubview:leftView];
    _leftView = leftView;
    
    // right
    UIView *rightView = [[UIView alloc] initWithFrame:];
     = [UIColor blueColor];
    [ addSubview:rightView];
    _rightView = rightView;
    
    // mainView
    UIView *mainView = [[UIView alloc] initWithFrame:];
     = [UIColor redColor];
    [ addSubview:mainView];
    _mainView = mainView;
}

2. Monitor the touch event and record the offset in the horizontal axis direction. With the offset, the position of the view can be changed by the offset.

#warning Second Cloth- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Get UITouch object    UITouch *touch = [touches anyObject];
    
    // Get the current point    CGPoint currentPoint = [touch locationInView:];
    
    // Get the previous point    CGPoint prePoint = [touch previousLocationInView:];
    
    // x-axis offset: how much does x offset when the finger moves a little    CGFloat offsetX =  - ;
    
    // Set the frame of the current main view    _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
    
    
    _isDraging = YES;
}
  How to listen for an object's properties in real time(Only listen to objects,Can't monitor structures)?kvo
  // 1. Listen  2, implement: observeValueForKeyPath method  /**
 * Add an observer to _mainView
      *
 * KeyPath: Listen to the frame property
      *
 * options: Listen to the changes in new values
 */
    [_mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; //Read the frame of mainview in real time 
 
// It will be called when the frame property of _mainView is changed- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@", NSStringFromCGRect(_mainView.frame));//The current frame    
    if (_mainView. &lt; 0) { // The x<0 of the main interface, move to the left        // Show the right        _rightView.hidden = NO;
        // Hide the left        _leftView.hidden = YES;
    }else if (_mainView. &gt; 0){ // Move to the right        // Show left        _rightView.hidden = YES;
        // Hide the right        _leftView.hidden = NO;
        
    }
} 

How to scale the height when the x-axis is offset?
When x is offset, the y-axis shrinks to: the offset of x/

#define HMMaxY 60
// When the finger is offset a little, calculate the frame of the current main view based on the offset of the X-axis- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX
{
    CGFloat screenW = [UIScreen mainScreen].;
    CGFloat screenH = [UIScreen mainScreen].;
    
    // Get the y-axis offset, every point of the finger moves, how much does the y-axis offset    CGFloat offsetY = offsetX * HMMaxY / screenW;//HMMaxY The maximum Y of the zoom    
    CGFloat scale = (screenH - 2 * offsetY) / screenH;//Proportion    
    if (_mainView. &lt; 0) { // Slide to the left        scale = (screenH + 2 * offsetY) / screenH;
    }
    
    // Get the previous frame    CGRect frame = _mainView.frame;
     += offsetX;
     =  *scale;
     =  *scale;
     = (screenH - ) * 0.5;
    
    return frame;
}

position:

#define HMRTarget 250
#define HMLTarget -220
/*
  _mainView. > screenW * 0.5 Position to the right
 CGRectGetMaxX(_mainView.frame) < screenW * 0.5 Position to the left -220
 
 */
// position- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    // Reset    if (_isDraging == NO &amp;&amp; _mainView. != 0) {
        [UIView animateWithDuration:0.25 animations:^{
            
            _mainView.frame = ;
        }];
    }
    
    
    CGFloat screenW = [UIScreen mainScreen].;
    
    CGFloat target = 0;
    if (_mainView. &gt; screenW * 0.5) { // Position to the right        target = HMRTarget;
    }else if (CGRectGetMaxX(_mainView.frame) &lt; screenW * 0.5) { // Position to the left        target = HMLTarget;
    }
    
    [UIView animateWithDuration:0.25 animations:^{
        
        if (target) { // If you need to locate the left or right            
            // Get the x-axis offset            CGFloat offsetX = target - _mainView.;
            
            // Set the frame of the current main view            _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
            
        }else{ // Restore            _mainView.frame = ;
        }
    }];
    
    _isDraging = NO;
    
}

Complete:

@interface HMDrawViewController ()
 
 
@property (nonatomic, assign) BOOL isDraging;
@end
 
@implementation HMDrawViewController
 
 
- (void)viewDidLoad
{
    // UIViewController
    [super viewDidLoad];
    // Do any additional setup after loading the view.
   
    // 1. Add child controls    [self addChildView];
#warning Step 3 Observe the frame changes of _mainView    // 2. Monitor    /**
 * Add an observer to _mainView
      *
 * KeyPath: Listen to the frame property
      *
 * options: Listen to the changes in new values
 */
    [_mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
   
}
 
// It will be called when the frame property of _mainView is changed- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@", NSStringFromCGRect(_mainView.frame));
    
    if (_mainView. &lt; 0) { // Move left        // Show the right        _rightView.hidden = NO;
        // Hide the left        _leftView.hidden = YES;
    }else if (_mainView. &gt; 0){ // Move to the right        // Show left        _rightView.hidden = YES;
        // Hide the right        _leftView.hidden = NO;
        
    }
}
 
#warning Step 1- (void)addChildView
{
    // left
    UIView *leftView = [[UIView alloc] initWithFrame:];
     = [UIColor greenColor];
    [ addSubview:leftView];
    _leftView = leftView;
    
    // right
    UIView *rightView = [[UIView alloc] initWithFrame:];
     = [UIColor blueColor];
    [ addSubview:rightView];
    _rightView = rightView;
    
    // mainView
    UIView *mainView = [[UIView alloc] initWithFrame:];
     = [UIColor redColor];
    [ addSubview:mainView];
    _mainView = mainView;
}
 
#warning Second Cloth- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Get UITouch object    UITouch *touch = [touches anyObject];
    
    // Get the current point    CGPoint currentPoint = [touch locationInView:];
    
    // Get the previous point    CGPoint prePoint = [touch previousLocationInView:];
    
    // x-axis offset: how much does x offset when the finger moves a little    CGFloat offsetX =  - ;
    
    // Set the frame of the current main view    _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
    
    
    _isDraging = YES;
}
#warning Step 4#define HMMaxY 60
// When the finger is offset a little, calculate the frame of the current main view based on the offset of the X-axis- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX
{
    CGFloat screenW = [UIScreen mainScreen].;
    CGFloat screenH = [UIScreen mainScreen].;
    
    // Get the y-axis offset, every point of the finger moves, how much does the y-axis offset    CGFloat offsetY = offsetX * HMMaxY / screenW;
    
    CGFloat scale = (screenH - 2 * offsetY) / screenH;
    
    if (_mainView. &lt; 0) { // Slide to the left        scale = (screenH + 2 * offsetY) / screenH;
    }
    
    // Get the previous frame    CGRect frame = _mainView.frame;
     += offsetX;
     =  *scale;
     =  *scale;
     = (screenH - ) * 0.5;
    
    return frame;
}
 
#define HMRTarget 250
#define HMLTarget -220
/*
  _mainView. > screenW * 0.5 Position to the right
 CGRectGetMaxX(_mainView.frame) < screenW * 0.5 Position to the left -220
 
 */
// position- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    // Reset    if (_isDraging == NO &amp;&amp; _mainView. != 0) {
        [UIView animateWithDuration:0.25 animations:^{
            
            _mainView.frame = ;
        }];
    }
    
    
    CGFloat screenW = [UIScreen mainScreen].;
    
    CGFloat target = 0;
    if (_mainView. &gt; screenW * 0.5) { // Position to the right        target = HMRTarget;
    }else if (CGRectGetMaxX(_mainView.frame) &lt; screenW * 0.5) { // Position to the left        target = HMLTarget;
    }
    
    [UIView animateWithDuration:0.25 animations:^{
        
        if (target) { // If you need to locate the left or right            
            // Get the x-axis offset            CGFloat offsetX = target - _mainView.;
            
            // Set the frame of the current main view            _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
            
        }else{ // Restore            _mainView.frame = ;
        }
    }];
    
    _isDraging = NO;
    
}

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.