網站首頁 編程語言 正文
本文實例為大家分享了iOS實現簡單抽屜效果的具體代碼,供大家參考,具體內容如下
實現思路及步驟:
1、首先準備要滑動的view
#warning 第一步
- (void)addChildView
{
? ? // left
? ? UIView *leftView = [[UIView alloc] initWithFrame:self.view.bounds];
? ? leftView.backgroundColor = [UIColor greenColor];
? ? [self.view addSubview:leftView];
? ? _leftView = leftView;
? ??
? ? // right
? ? UIView *rightView = [[UIView alloc] initWithFrame:self.view.bounds];
? ? rightView.backgroundColor = [UIColor blueColor];
? ? [self.view addSubview:rightView];
? ? _rightView = rightView;
? ??
? ? // mainView
? ? UIView *mainView = [[UIView alloc] initWithFrame:self.view.bounds];
? ? mainView.backgroundColor = [UIColor redColor];
? ? [self.view addSubview:mainView];
? ? _mainView = mainView;
}
2、監聽觸摸事件,記錄橫軸方向的偏移量,有了偏移量就可以通過偏移量改動視圖的位置
#warning 第二布
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
? ? // 獲取UITouch對象
? ? UITouch *touch = [touches anyObject];
? ??
? ? // 獲取當前點
? ? CGPoint currentPoint = [touch locationInView:self.view];
? ??
? ? // 獲取上一個點
? ? CGPoint prePoint = [touch previousLocationInView:self.view];
? ??
? ? // x軸偏移量:當手指移動一點的時候,x偏移多少
? ? CGFloat offsetX = currentPoint.x - prePoint.x;
? ??
? ? // 設置當前主視圖的frame
? ? _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
? ??
? ??
? ? _isDraging = YES;
}
? 如何實時監聽一個對象的屬性(只能監聽對象,不能監聽結構體)?kvo
? // 1.監聽 ?2 ,實現:observeValueForKeyPath 方法
? /**
? ? ?* ?給_mainView添加一個觀察者
? ? ?*
? ? ?* ?KeyPath:監聽frame這個屬性
? ? ?*
? ? ?* ?options:監聽新值的改變
? ? ?*/
? ? [_mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; //實時監聽mainview的frame
?
?
// 當_mainView的frame屬性改變的時候就會調用
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
? ? NSLog(@"%@", NSStringFromCGRect(_mainView.frame));//當前的frame
? ??
? ? if (_mainView.frame.origin.x < 0) { // 主界面的x<0,往左移動
? ? ? ? // 顯示右邊
? ? ? ? _rightView.hidden = NO;
? ? ? ? // 隱藏左邊
? ? ? ? _leftView.hidden = YES;
? ? }else if (_mainView.frame.origin.x > 0){ // 往右移動
? ? ? ? // 顯示左邊
? ? ? ? _rightView.hidden = YES;
? ? ? ? // 隱藏右邊
? ? ? ? _leftView.hidden = NO;
? ? ? ??
? ? }
}?
當x軸偏移的時候,如何縮放高度?
當x偏移時,y軸縮小為: x的偏移量/
#define HMMaxY 60
// 當手指偏移一點,根據X軸的偏移量算出當前主視圖的frame
- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX
{
? ? CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
? ? CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
? ??
? ? // 獲取y軸偏移量,手指每移動一點,y軸偏移多少
? ? CGFloat offsetY = offsetX * HMMaxY / screenW;//HMMaxY 縮放的最大Y?
? ??
? ? CGFloat scale = (screenH - 2 * offsetY) / screenH;//比例?
? ??
? ? if (_mainView.frame.origin.x < 0) { // 往左邊滑動
? ? ? ? scale = (screenH + 2 * offsetY) / screenH;
? ? }
? ??
? ? // 獲取之前的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;
}
定位:
#define HMRTarget 250
#define HMLTarget -220
/*
?_mainView.frame.origin.x > screenW * 0.5 定位到右邊
? CGRectGetMaxX(_mainView.frame) < screenW * 0.5 定位到左邊 -220
?
?*/
// 定位
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
? ??
? ? // 復位
? ? if (_isDraging == NO && _mainView.frame.origin.x != 0) {
? ? ? ? [UIView animateWithDuration:0.25 animations:^{
? ? ? ? ? ??
? ? ? ? ? ? _mainView.frame = self.view.bounds;
? ? ? ? }];
? ? }
? ??
? ??
? ? CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
? ??
? ? CGFloat target = 0;
? ? if (_mainView.frame.origin.x > screenW * 0.5) { // 定位到右邊
? ? ? ? target = HMRTarget;
? ? }else if (CGRectGetMaxX(_mainView.frame) < screenW * 0.5) { // 定位到左邊
? ? ? ? target = HMLTarget;
? ? }
? ??
? ? [UIView animateWithDuration:0.25 animations:^{
? ? ? ??
? ? ? ? if (target) { // 在需要定位左邊或者右邊
? ? ? ? ? ??
? ? ? ? ? ? // 獲取x軸偏移量
? ? ? ? ? ? CGFloat offsetX = target - _mainView.frame.origin.x;
? ? ? ? ? ??
? ? ? ? ? ? // 設置當前主視圖的frame
? ? ? ? ? ? _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
? ? ? ? ? ??
? ? ? ? }else{ // 還原
? ? ? ? ? ? _mainView.frame = self.view.bounds;
? ? ? ? }
? ? }];
? ??
? ? _isDraging = NO;
? ??
}
全:
@interface HMDrawViewController ()
?
?
@property (nonatomic, assign) BOOL isDraging;
@end
?
@implementation HMDrawViewController
?
?
- (void)viewDidLoad
{
? ? // UIViewController
? ? [super viewDidLoad];
? ? // Do any additional setup after loading the view.
? ?
? ? // 1.添加子控件
? ? [self addChildView];
#warning 第三步 觀察_mainView的frame改變
? ? // 2.監聽
? ? /**
? ? ?* ?給_mainView添加一個觀察者
? ? ?*
? ? ?* ?KeyPath:監聽frame這個屬性
? ? ?*
? ? ?* ?options:監聽新值的改變
? ? ?*/
? ? [_mainView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
? ?
}
?
// 當_mainView的frame屬性改變的時候就會調用
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
? ? NSLog(@"%@", NSStringFromCGRect(_mainView.frame));
? ??
? ? if (_mainView.frame.origin.x < 0) { // 往左移動
? ? ? ? // 顯示右邊
? ? ? ? _rightView.hidden = NO;
? ? ? ? // 隱藏左邊
? ? ? ? _leftView.hidden = YES;
? ? }else if (_mainView.frame.origin.x > 0){ // 往右移動
? ? ? ? // 顯示左邊
? ? ? ? _rightView.hidden = YES;
? ? ? ? // 隱藏右邊
? ? ? ? _leftView.hidden = NO;
? ? ? ??
? ? }
}
?
#warning 第一步
- (void)addChildView
{
? ? // left
? ? UIView *leftView = [[UIView alloc] initWithFrame:self.view.bounds];
? ? leftView.backgroundColor = [UIColor greenColor];
? ? [self.view addSubview:leftView];
? ? _leftView = leftView;
? ??
? ? // right
? ? UIView *rightView = [[UIView alloc] initWithFrame:self.view.bounds];
? ? rightView.backgroundColor = [UIColor blueColor];
? ? [self.view addSubview:rightView];
? ? _rightView = rightView;
? ??
? ? // mainView
? ? UIView *mainView = [[UIView alloc] initWithFrame:self.view.bounds];
? ? mainView.backgroundColor = [UIColor redColor];
? ? [self.view addSubview:mainView];
? ? _mainView = mainView;
}
?
#warning 第二布
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
? ? // 獲取UITouch對象
? ? UITouch *touch = [touches anyObject];
? ??
? ? // 獲取當前點
? ? CGPoint currentPoint = [touch locationInView:self.view];
? ??
? ? // 獲取上一個點
? ? CGPoint prePoint = [touch previousLocationInView:self.view];
? ??
? ? // x軸偏移量:當手指移動一點的時候,x偏移多少
? ? CGFloat offsetX = currentPoint.x - prePoint.x;
? ??
? ? // 設置當前主視圖的frame
? ? _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
? ??
? ??
? ? _isDraging = YES;
}
#warning 第四步
#define HMMaxY 60
// 當手指偏移一點,根據X軸的偏移量算出當前主視圖的frame
- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX
{
? ? CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
? ? CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
? ??
? ? // 獲取y軸偏移量,手指每移動一點,y軸偏移多少
? ? CGFloat offsetY = offsetX * HMMaxY / screenW;
? ??
? ? CGFloat scale = (screenH - 2 * offsetY) / screenH;
? ??
? ? if (_mainView.frame.origin.x < 0) { // 往左邊滑動
? ? ? ? scale = (screenH + 2 * offsetY) / screenH;
? ? }
? ??
? ? // 獲取之前的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;
}
?
#define HMRTarget 250
#define HMLTarget -220
/*
?_mainView.frame.origin.x > screenW * 0.5 定位到右邊
? CGRectGetMaxX(_mainView.frame) < screenW * 0.5 定位到左邊 -220
?
?*/
// 定位
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
? ??
? ? // 復位
? ? if (_isDraging == NO && _mainView.frame.origin.x != 0) {
? ? ? ? [UIView animateWithDuration:0.25 animations:^{
? ? ? ? ? ??
? ? ? ? ? ? _mainView.frame = self.view.bounds;
? ? ? ? }];
? ? }
? ??
? ??
? ? CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
? ??
? ? CGFloat target = 0;
? ? if (_mainView.frame.origin.x > screenW * 0.5) { // 定位到右邊
? ? ? ? target = HMRTarget;
? ? }else if (CGRectGetMaxX(_mainView.frame) < screenW * 0.5) { // 定位到左邊
? ? ? ? target = HMLTarget;
? ? }
? ??
? ? [UIView animateWithDuration:0.25 animations:^{
? ? ? ??
? ? ? ? if (target) { // 在需要定位左邊或者右邊
? ? ? ? ? ??
? ? ? ? ? ? // 獲取x軸偏移量
? ? ? ? ? ? CGFloat offsetX = target - _mainView.frame.origin.x;
? ? ? ? ? ??
? ? ? ? ? ? // 設置當前主視圖的frame
? ? ? ? ? ? _mainView.frame = [self getCurrentFrameWithOffsetX:offsetX];
? ? ? ? ? ??
? ? ? ? }else{ // 還原
? ? ? ? ? ? _mainView.frame = self.view.bounds;
? ? ? ? }
? ? }];
? ??
? ? _isDraging = NO;
? ??
}
原文鏈接:https://blog.csdn.net/PZ0605/article/details/45953635
相關推薦
- 2023-04-02 使用Pytorch如何完成多分類問題_python
- 2024-01-31 Mybatis plus并發更新時的問題
- 2022-07-29 Golang的鎖機制與使用技巧小結_Golang
- 2023-05-16 Android中的HOOK技術是什么_Android
- 2022-04-07 C++11生成隨機數(random庫)的使用_C 語言
- 2022-01-21 面試題:說一說es6新增方法
- 2022-03-23 Android?app啟動圖適配方法實例_Android
- 2022-05-13 C++ Poco庫的編譯和使用
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支