年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6339|回复: 3

[实用控件] ios实战开发之按钮控件

[复制链接]
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

    发表于 2014-3-25 18:31:11 | 显示全部楼层 |阅读模式
    本帖最后由 Sian 于 2014-3-26 00:04 编辑

    1、直接效果展示:



    2、基本过程分析:
    1、新建一个ios的Application--Single View Application项目
    2、创建六个按钮控件,其中一个按钮控件的受控体,四个按钮控件来控件其上、下、左、右运动,另外一个按钮控制其顺时针旋转
    3、按钮创建通过storyboard直接在可视面板上画出来,并调整好相关位置布局到手机屏幕;
    4、每个按钮对应两张按钮图片,两张图片形状大小相同,但颜色不同,这样可以达到按下按钮变色的效果;
    5、图形界面设计主要运用storyboard的功能,需要对这块有所了解;
    6、编写按钮方法主要涉及到两个文件:ViewController.h与ViewController.m文件

    3、主体代码及相关说明
    ViewController.h
    1. //
    2. //  SAViewController.h
    3. //  UIView
    4. //
    5. //  Created by yusian on 14-3-25.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import <UIKit/UIKit.h>
    9. @interface SAViewController : UIViewController
    10. // 创建一个按钮属性,通过拖拽的方式自动添加
    11. @property (weak, nonatomic) IBOutlet UIButton *img;
    12. // 添加一个按钮事件,用来控制上、下、左、右
    13. - (IBAction)control:(id)sender;
    14. // 添加一个按钮事件,用来控制旋转(放大)功能;
    15. - (IBAction)rotate:(id)sender;
    16. // 添加一个按钮事件,实现复位功能
    17. - (IBAction)reset:(id)sender;
    18. @end
    复制代码
    ViewController.m
    1. //
    2. //  SAViewController.m
    3. //  UIView
    4. //
    5. //  Created by yusian on 14-3-25.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import "SAViewController.h"
    9. @interface SAViewController ()
    10. @end
    11. @implementation SAViewController
    12. // 上、下、左、右按钮实现
    13. - (IBAction)control:(id)sender
    14. {
    15.     // 首尾的三个UIView类方法,实现控件移动时能平滑运动,beginAnimations: context: 动画开始
    16.     [UIView beginAnimations:nil context:nil];
    17.    
    18.     // 设置动画时间,0.4表示控件移动耗时0.4秒
    19.     [UIView setAnimationDuration:0.4];
    20.    
    21.     // 控件移动代码开始(为了更清晰地展示,所以使用{}将该部分区分,此处{}可去掉)
    22.     {
    23.         // 由于不能直接修改类中结构体成员变量,只能整体修改结构体,所以先将结构体值取出到一个临时变量(img为需要移动的控件对象名称,.h文件中有成员变量声明)
    24.         CGRect rect = self.img.frame;
    25.         
    26.         // 该方法传进来的形参sender为按钮对象,四个按钮可以写四个方法分别来实现各自的动作,但由于动作基本相同,为避免重复代码过多,这里通过按钮对象的tag来区分传进来的按钮,并分别修改值
    27.         
    28.         // 使用sender的get方法取tag值,tag值在创建按钮时分别修改,图形界面操作(这里不能使用点语法,即sender.tag编译器没有自动转换成相应的get方法)
    29.         switch ([sender tag]) {
    30.             
    31.             // 向上按钮的tag值为1,如果需要控件向上移动,则y值减30,结果整个控件向上移动30个像素
    32.             case 1:
    33.                 rect.origin.y -= 30;
    34.                 break;
    35.                
    36.             // 向右按钮的tag值为2
    37.             case 2:
    38.                 rect.origin.x += 30;
    39.                 break;
    40.             
    41.             // 同理,向下按钮
    42.             case 3:
    43.                 rect.origin.y += 30;
    44.                 break;
    45.                
    46.             // 向左按钮
    47.             case 4:
    48.                 rect.origin.x -= 30;
    49.                 break;
    50.         }
    51.         
    52.         // 将修改过后的结构体整体赋值给按钮,完成修改相关参数
    53.         self.img.frame = rect;
    54.         
    55.     }// 控件移动代码结束
    56.    
    57.     // 第三个UIView类方法表示动画结束,类方法之间部分将实现动画效果,没有这三个类方法程序照样能正常运行,效果为瞬间移动
    58.     [UIView commitAnimations];
    59. }
    60. // 旋转/放大按钮的实现
    61. - (IBAction)rotate:(id)sender
    62. {
    63.     // 动画部分,三个UIView类方法,具体使用与上一个方法完全相同
    64.     [UIView beginAnimations:nil context:nil];
    65.    
    66.     [UIView setAnimationDuration:0.4];
    67.    
    68.     // 旋转可直接调用CoreGraphics框架中的一个函数来实现,函数结果返回transform结构体,函数需要传递两个参数,一个是基础转换体,另一个旋转弧度,M_PI_4为1/4π,即45度
    69.     self.img.transform = CGAffineTransformRotate(self.img.transform, M_PI_4);
    70.    
    71.     // 放大同样的相对应的函数实现
    72.     // self.img.transform = CGAffineTransformScale(self.img.transform, 0.9, 0.9);
    73.    
    74.     // 动画结束
    75.     [UIView commitAnimations];
    76. }
    77. - (IBAction)reset:(id)sender
    78. {
    79.    
    80.     [UIView beginAnimations:nil context:nil];
    81.    
    82.     [UIView setAnimationDuration:0.4];
    83.    
    84.     // 复原比较简单,转换复原可直接调用一个常量“CGAffineTransformIdentity”赋值即可,说明旋转变形只是一种临时表现形式,原值有专用的常量保存
    85.     self.img.transform = CGAffineTransformIdentity;
    86.    
    87.     // 位移动还原有多种方式,事实上也是一次位移操作,将原始位置再次赋值给控件即可,使用self.img.frame赋值,也可以使用更为简单的center,center为CGPoint类型结构体,没有长宽参数,只有位置参数,如果长宽没有变化使用center更合理
    88.     self.img.center = CGPointMake(160, 90);
    89.    
    90.     [UIView commitAnimations];
    91.    
    92. }
    93. /***************** 代码重构 ******************
    94. // 以上三个方法有一个共同特性:都有三行相同的动画代码,事实上- (IBAction)control:(id)sender方法中已经进行了一次重构,将三个按钮的方法合成了一个,这里将三个方法中动画代码抽取出来;
    95. // 基本思路:通过一个函数实现动画,由于动画的三行代码非连续,所以不能直接使用函数实现,中间的业务代码通过block的传入来实现,即实现一个以block为形参的函数来完成重构
    96. // 函数形参为void (^block) () ,具体block的使用可参考block相关知识
    97. - (void)actionWithBlock:(void (^)())block
    98. {
    99.     [UIView beginAnimations:nil context:nil];
    100.    
    101.     [UIView setAnimationDuration:0.4];
    102.    
    103.     block();
    104.    
    105.     [UIView commitAnimations];
    106.    
    107. }
    108. - (IBAction)control:(id)sender
    109. {
    110.     // 该方法的实现只需要调用本对象的一个方法即可实现,将具体业务代码通过block传进函数;
    111.     [self actionWithBlock:^(){
    112.         
    113.         
    114.         CGRect rect = self.img.frame;
    115.         
    116.         switch ([sender tag]) {
    117.             case 1:
    118.                 rect.origin.y -= 30;
    119.                 break;
    120.                
    121.             case 2:
    122.                 rect.origin.x += 30;
    123.                 break;
    124.                
    125.             case 3:
    126.                 rect.origin.y += 30;
    127.                 break;
    128.                
    129.             case 4:
    130.                 rect.origin.x -= 30;
    131.                 break;
    132.         }
    133.         
    134.         self.img.frame = rect;
    135.         
    136.     }];
    137.    
    138. }
    139. - (IBAction)rotate:(id)sender
    140. {
    141.    
    142.     [self actionWithBlock:^() {
    143.         
    144.         // 顺时针旋转
    145.         self.img.transform = CGAffineTransformRotate(self.img.transform, M_PI_4);
    146.         // 放大
    147.         // self.img.transform = CGAffineTransformScale(self.img.transform, 0.9, 0.9);
    148.         
    149.     }];
    150.    
    151. }
    152. - (IBAction)reset:(id)sender
    153. {
    154.     [self actionWithBlock:^() {
    155.         self.img.transform = CGAffineTransformIdentity;
    156.         self.img.center = CGPointMake(160, 90);
    157.     }];
    158. }
    159. *******************  end  **********************/
    160. @end
    复制代码

    源代码下载:
    游客,本帖隐藏的内容需要积分高于 1 才可浏览,您当前积分为 0

    运行结果:
    screen.png


    参考链接:



    该用户从未签到

    发表于 2014-12-9 10:33:03 | 显示全部楼层
    楼主要是能把开发环境和开发软件版本讲一下就好了,现在版本太多,容易搞混淆:)
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

     楼主| 发表于 2014-12-9 22:32:05 | 显示全部楼层
    zj0517 发表于 2014-12-9 10:33
    楼主要是能把开发环境和开发软件版本讲一下就好了,现在版本太多,容易搞混淆

    这个只是熟悉下UI的基本操作,跟版本关系不大,我当时的开发环境是Xcode4.6 iOS6的SDK,实际上你用Xcode5,iOS7的SDK也基本上没问题。都是ARC的无所谓...

    该用户从未签到

    发表于 2014-12-10 21:20:08 | 显示全部楼层
    Sian 发表于 2014-12-9 22:32
    这个只是熟悉下UI的基本操作,跟版本关系不大,我当时的开发环境是Xcode4.6 iOS6的SDK,实际上你用Xcode5 ...

    哈哈,楼主太强大了算的真准,确实现在用的5.1.1没有升级优山美地,刚刚接触IOS多像楼主学习。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|小黑屋|Archiver|iOS开发笔记 ( 湘ICP备14010846号 )

    GMT+8, 2024-4-27 14:15 , Processed in 0.057475 second(s), 24 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表