UIButton

UIButton做frame动画时,不响应点击

  • 在一个View内部加入几个按钮,然后改变这个view的frame来做动画,但是按钮不响应点击事件。

  • 问题代码

    __block CGRect rect = _scrollView.frame;
CGFloat width = [UIScreen mainScreen].bounds.size.width;
[UIView setAnimationsEnabled:YES];
[UIView animateWithDuration:0.3f animations:^{
rect.origin.x -= 10;
if (rect.origin.x <= - width) {
// 添加下一个scrollView到self
[UIView setAnimationsEnabled:NO];
rect.origin.x = width + 10; }
_scrollView.frame = rect;
} completion:^(BOOL finished) { }];
  • 解决问题
    [UIView animateWithDuration:0.3f delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
rect.origin.x -= 10;
if (rect.origin.x <= - width) {
// 添加下一个scrollView到self
[UIView setAnimationsEnabled:NO];
rect.origin.x = width + 10;
}
_scrollView.frame = rect;
} completion:^(BOOL finished) { }];
  • 结论

    - 应该是在改变一个控件的frame做动画时,控件的交互被关闭了,所以要在做动画时改变方法,手动开启交互。

UIButton 内部布局变化

  • 控件竖排

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_focusBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_focusBtn.frame = CGRectMake(10, 100, 52, 52);
_focusBtn.backgroundColor = [UIColor greenColor];
[_focusBtn setTitle:@"关注" forState:UIControlStateNormal]; CGFloat buttonWidth = 52;
CGFloat textWidth = 30;
CGFloat imageWidth = 19;
[_focusBtn setImage:[UIImage imageNamed:@"focusBtn"] forState:UIControlStateNormal];
[_focusBtn setBackgroundImage:[UIImage imageNamed:@"redcolor"] forState:UIControlStateNormal];
[_focusBtn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[_focusBtn setContentVerticalAlignment:UIControlContentVerticalAlignmentTop]; [_focusBtn setImageEdgeInsets:UIEdgeInsetsMake(6,(52-20)/2, 0, _focusBtn.titleLabel.bounds.size.width )];
[_focusBtn setTitleEdgeInsets:UIEdgeInsetsMake(17.5 + 6 , - ([_focusBtn currentImage].size.width) + 7 , 9,0 )]; [self.view addSubview:_focusBtn]; }

UIButton 默认布局

  • 默认布局是横排:图片在左,label在右,并且居中方式是水平居中对齐,垂直居中对齐。

    • 紫色是image的frame,绿色是label的frame,黄色是button的frame
    • 如果要改变为竖排,那么首先要把对齐方式改为水平靠左,垂直靠上。
    • 然后再设置每个子控件的UIEdgeInsets
    • 最终展示效果是这样的
    • 中间过渡过程是这样的
    • 由此图可见,image要的left要右移,也就是增大正数,但是label的left要左移,也就是要减小为负数。
    • 这里总结一下,UIEdgeInsets的top,left,bottom,right属性,分别表示处于父控件的内部边距,如left,为正数,表示右移多少,为负数,表示左移多少。
    [_focusBtn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[_focusBtn setContentVerticalAlignment:UIControlContentVerticalAlignmentTop];
  • 注:在iOS中,UIEdgeInsets跟web中的padding一样的分top,left,bottom和right,正数就表示与周围的距离变大,例如:默认在是0,我把top变成了10,这时该元素与顶端的距离就会增加10,即元素下移,距离变大。如果是负数的话效果就相反了,距离拉近。
     [_focusBtn setImageEdgeInsets:UIEdgeInsetsMake(6,(52-20)/2, 0, _focusBtn.titleLabel.bounds.size.width )];
[_focusBtn setTitleEdgeInsets:UIEdgeInsetsMake(17.5 + 6 , - ([_focusBtn currentImage].size.width) + 7 , 9,0 )];
  • 这样的效果就是

label居中问题

  • 下午计算文字的宽度的时候一直出问题,主要是根据文字宽度计算内边距,但是文字长度不等,对这个布局有很大影响。
- (void)focusedBtn:(NSInteger)number
{
_focusedBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, 52, 52)];
NSString *title = @"";
if (number >= 10000)
{
title = [NSString stringWithFormat:@"%.1f万",number/10000.0];
}
else
{
title = [NSString stringWithFormat:@"%zd",number]; } [_focusedBtn setTitle:title forState:UIControlStateNormal]; UILabel *lab = [[UILabel alloc] init];
lab.text = @"1";
lab.font = [UIFont systemFontOfSize:12]; // font 12 : label.width 7
[lab sizeToFit];
NSLog(@"%@",NSStringFromCGSize(lab.bounds.size)); NSLog(@"buttuon:%@",NSStringFromCGRect(_focusedBtn.frame));
NSLog(@"imageView:%@",NSStringFromCGRect(_focusedBtn.imageView.frame));
NSLog(@"textLabel:%@",NSStringFromCGRect(_focusedBtn.titleLabel.frame));
NSLog(@"---------------------"); CGFloat buttonWidth = 52;
CGFloat textWidth = 40;
CGFloat imageWidth = 19;
CGFloat imageHeight = 19;
[_focusedBtn setImage:[UIImage imageNamed:@"focusBtn"] forState:UIControlStateNormal]; // 关注后这个图片改变了
[_focusedBtn setBackgroundImage:[UIImage imageNamed:@"redcolor"] forState:UIControlStateNormal];
[_focusedBtn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[_focusedBtn setContentVerticalAlignment:UIControlContentVerticalAlignmentTop]; [_focusedBtn setImageEdgeInsets:UIEdgeInsetsMake(6,(buttonWidth-imageWidth)/2, 0, 0 )]; [_focusedBtn.titleLabel setFont:[UIFont systemFontOfSize:12.0f]];
[_focusedBtn.titleLabel setContentMode:UIViewContentModeCenter];
_focusedBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
[_focusedBtn.titleLabel sizeToFit];
// 我尝试在label宽度基础上加上一个字符宽度。只要字符不超过一定长度,显示就没有问题,这个调整具体问题具体分析
[_focusedBtn setTitleEdgeInsets:UIEdgeInsetsMake(imageHeight + 10 ,- _focusedBtn.titleLabel.bounds.size.width/2 + 7, 9,0)]; NSLog(@"buttuon:%@",NSStringFromCGRect(_focusedBtn.frame));
NSLog(@"imageView:%@",NSStringFromCGRect(_focusedBtn.imageView.frame));
NSLog(@"textLabel:%@",NSStringFromCGRect(_focusedBtn.titleLabel.frame)); [self.view addSubview:_focusedBtn];
}

总结: 这个UIButton的内部控件的自定义,位置调整最重要。

- 1、首先要改变内部控件的对其方式,`setContentHorizontalAlignment` `setContentVerticalAlignment`
- 2、然后重新设置每个子控件的内部间距,这个设置要注意,如果要实现比较好的效果,需要精细调整。
- 3、其实主要是理解`UIEdgeInsets`的使用。`UIEdgeInsets`内部包含四个值{top,left,bottom,right},每个值都是以自身位置为标准进行偏移。比如top,为正数时向下偏移,负数向上偏移。所以对子控件进行布局时一定要明确最初所处的位置。

UIButton内部子控件自定义布局-“UIEdgeInsets”的更多相关文章

  1. UIScrollView子控件的布局

    scorllView内部子控件添加约束的注意点: 1.子控件的尺寸不能通过UIScrollView来计算 *比如可以设置固定值 (width==100 height ==100) *比如可以相对于UI ...

  2. iOS开发小技巧--UIScrollView内部子控件添加约束的注意点

    注意:用UIScrollView时布局子控件的时候,不要相对于UIScrollView来添加约束,这样做不是设置子控件的位置,反而是设置了UIScrollView的contentSize 子控件的尺寸 ...

  3. WPF的ListView控件自定义布局用法实例

    正文: 如何布局是在App.xaml中定义源码如下 <Application x:Class="CWebsSynAssistant.App"   xmlns="ht ...

  4. 禁止ScrollView在子控件的布局改变时自动滚动的的方法

    重写scrollview中的如下方法,并将其返回值设为0即可. @Override  protected int computeScrollDeltaToGetChildRectOnScreen(Re ...

  5. iPad开发--QQ空间,处理横竖屏布局,实现子控件中的代理

    一.主界面横竖屏效果图 二.主界面加载, 初始化Dock(红色框的控件),判断程序启动时的屏幕方向.调用自己- (void)transitionToLandScape:(BOOL)isLandScap ...

  6. 记录下UIButton的图文妙用和子控件的优先显示

    UIButton的用处特别多,这里只记录下把按钮应用在图文显示的场景,和需要把图片作为按钮的背景图片显示场景: 另外记录下在父控件的子控件优先显示方法(控件置于最前面和置于最后面). 先上效果图: 1 ...

  7. Duilib源码分析(五)UI布局—Layout与各子控件

    接下来,继续分析duilib之UI布局Layout,目前提供的布局有:VerticalLayout.HorizontalLayout.TileLayout.TabLayout.ChildLayout分 ...

  8. Android自定义组合控件内子控件无法显示问题

    今天自定义了一个组合控件,与到了个奇葩问题: 我自定义了一个RelativeLayout,这个layout内有多个子控件.但奇怪的是这些子控件一直显示不出来.调试了一下午,竟然是因为在获取(infla ...

  9. WPF 的内部世界(控件与布局)

    目录 一.控件与布局 前言 为什么要写WPF呢? 我一开始算是比较抵触WPF的,因为用的人少吗.感觉都是窗体应用能和Winform有什么区别.可是我错了,非常感谢我的讲师,给我推荐刘铁猛的<深入 ...

随机推荐

  1. 【转】应用程序的入口是ActivityThread

    ActivityThread运行框架 在分析中,我们可以看到真正对应应用进程的不是Application而是ActivityThread.我们从实际的应用堆栈可以看到: NavitiveStart.m ...

  2. EJB3 调用的存储过程

    要调用存储过程,我们可以通过 EntityManager 对象的 createNativeQuery()方法执行 SQL 语句 (注意:这里说的是SQL 语句,不是 EJB3 QL), 调用存储过程的 ...

  3. Android学习笔记_3_四种布局

    Android布局是应用界面开发的重要一环,在Android中,共有四种布局方式, 分别是:FrameLayout( 帧布局 ).LinearLayout (线性布局).TableLayout(表格布 ...

  4. MYSQL添加外键关联

    SELECT * from stu st,course co,score sc where st.sid = sc.sid and sc.cid = co.cid 如果我们要给 sid 做一个约束,即 ...

  5. tomcate8配置多个二级域名问题解决根目录空白2017年12月9日

    <Host name="localhost" appBase="webapps" unpackWARs="true" autoDepl ...

  6. html单选框(性别选择)

    在写单选框时,如何实现只能同时只能选择一个radio. 将name设置为一样的数值:代码如下: <input class="myforms-3-2" type="r ...

  7. Oracle闪回恢复误删除的表、存储过程、包、函数...

    在日常的数据库开发过程汇总难免会出现一些误删除的动作, 对于一些误删的操作我们可以通过oracle提供的闪回机制恢复误删数据, 从而避免出现较大的生产事故. 下面是本人平时工作中积累的一些常用的操作, ...

  8. TortoiseSVN SendRpt.exe not found解决方案

    重启了Explorer.exe即可.这里也补充下简单的重启Explorer.exe的方法:打开任务管理器,找到“Windows资源管理器”,右键--重新启动. 或者,右键--结束任务,然后点击 文件- ...

  9. ETO的公开赛T1《矿脉开采》题解(正解)(by Zenurik)

    作为T1,当然是越水越好啦qwq 显然经目测可得,那个所谓的质量评级根本就没卵用,可以直接\(W_i = W_i^{V_i}\)累积到利润里面. 这样,本问题显然是一个"子集和"问 ...

  10. MySql Connector/C++8结果集处理Demo

    #include <iostream> #include <exception> #include <mysqlx/xdevapi.h> using std::co ...