iOS ios开发日历控件,为什么不喜欢用拖控件

iOS - Fountion框架(47)
iOS - 性能优化(21)
一、在OC中,如果对象没有强引用,就会被自动释放,那么为什么控件还可以设为weak?
我们平时定义控件属性的时候一般都会用strong修饰符,而我们在用xib,sb拖控件的时候会发现,这时属性都是用的weak修饰符。
1. 从storyboard或者xib上创建控件,在控件放在view上的时候,已经形成了如下的引用关系,以UIButton为例:
UIViewController-&UIView-&subView-&UIButton
然后你为这个UIButton声明一个weak属性
@property(nonatomic,weak) IBOOutlet UIButton *btn;
相当于xib/sb对这个Button是强引用,你声明的属性对它是弱引用。
2.手动创建控件
a). 将控件声明成strong
@property(nonatomic,strong) UIButton *btn;
那么你在实现这个控件时只需这样:
_btn = [[UIButton alloc]init];
[self.view addSubview:_btn]
b). 将控件声明成weak
@property(nonatomic,weak) UIButton *
那么你在实现这个控件时需要这样:
UIButton *button = [[UIButton alloc]init];
[self.view addSubview:_btn];
最近看的黑马iOS视频上给的建议的是:
1.如果用Stroyboard拖线,用weak
2.如果自定对象,用strong
事实上IBOutlet的属性一般可以设为weak是因为它已经被view引用了,除非view被释放,否则IBOutlet的属性也不会被释放,另外IBOutlet属性的生命周期和view应该是一致的,所以IBOutlet属性一般设为weak。
二、下面我们来说说delegate为啥定义时要用weak修饰符,这个涉及到循环引用的问题。例如一个ViewController上通过强指针引用了一个tableview,tableview的datasource和delegate都必须是weak指针,因为viewController被他两指向,如果用strong的话,就会形成强引用循环。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:118297次
积分:3426
积分:3426
排名:第7474名
原创:192篇
转载:254篇
(8)(8)(5)(3)(2)(1)(10)(18)(41)(190)(163)(5)iOS开发之基于AotoLayout的控件悬停 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了13157字,被197人关注,获得了137个喜欢
iOS开发之基于AotoLayout的控件悬停
在很多的电商类的APP中我们经常会用到一种滑动悬停的效果,所以这次尝试着利用AutoLayout来实现这种效果。话不多说先上图
效果上过了,还是理顺下思路上吧。从效果图上不难发现我们的程序是基于UIScrollerView的。界面上的展示同样都是UIScrollView的子控件。当然了难点也就是基于UIScrollerView的内部子控件的布局以及AutoLayout约束的修改。
我们看一下我们的需要的一些基本的控件布局:
好了,现在开始开始搭建新的项目了,首先在Storyboard上搭建最基本的布局,并将控件基本布局到相应的位置,以备我们更方便的添加约束。
到了这里就开始对我们的控件添加基本的约束了从上开始吧。上面的控件我们能确定是UIImageView的heigth以及top、left以及rihgt。至于bottom到了后面会着重设置的。
然后继续来操作悬停的View。这个View因为处在两个view的中间所以我们要暂时确定height以及left和right的约束就足够了了
终于到最后一个UIImageView了,同样的能确定的是height、right、left以及bottom这四项。
到了这里针对单个的控件的布局基本完成了,细心的你可能会发现以上的操作都没有进行关联以及没有对width进行约束。那么下面我们就要开始进行三者的关联以及width上的设置。
因为悬停的view处与两个imageView的中间,所以我们只需要对它进行处理就好了
其实这两个约束完全是可以在设置悬停view的时候的添加,之所以在这里添加是我们在后面的控制器会用到这两个约束,为了好辨认我们就给他们定义上别名:
然后我们按住command选择我们的三个控件然后按住control拖向scrollView的父控件view设置等width。
好了,到了这里我们的约束已经不会再报错了,然后在逻辑上也是基本是通顺的了,但是对于我们悬停的功能来说就少了关键的一个环节那么就是一旦悬停view悬停了,那么它与上下两个imageView的约束要怎么处理呢?所以我们还需要一个辅助的约束用来悬停之后的关联处理
添加之后我们给这个约束起个别名hidden悬停,不过细心的你一定会发现添加之后会sb会提示出有冲突的约束,那么我们只需要对我们刚刚添加的约束进行一下操作就OK了
好了,到了这里我们在AutoLayout上要做的事情就这些了,下面我们就可以安心的写代码了。
@interface ViewController ()
/**中间的View*/
@property (weak, nonatomic) IBOutlet UIView *centreV
/**上面的ImageView*/
@property (weak, nonatomic) IBOutlet UIImageView *topImageV
/**centreView的top约束*/
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topC
/**centreView的bottom约束*/
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomC
/**topImageView暂禁用的约束*/
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *hiddenC
然后在scrollView的滑动代理方法中实现
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//获得top图片的高度
CGFloat imageH = self.topImageView.frame.size.
//获取偏移量
CGFloat offsetY = scrollView.contentOffset.y;
//centrView的frame
CGRect centreFrame = self.centreView.
if (offsetY&=imageH) {
//将centreView的向上和向下的约束禁用
self.bottomConstraint.active = NO;
self.topConstraint.active = NO;
//将topImageView与bottomImageView的约束使用关联
self.hiddenConstraint.active = YES;
//悬停在位置
centreFrame.origin.y = 0;
self.centreView.frame = centreF
//添加在scrollView的父控件
[self.view addSubview:self.centreView];
//添加在topIamgeView的下面
centreFrame.origin.y = imageH;
self.centreView.frame = centreF
[scrollView addSubview:self.centreView];
//记住一定要先添加到scrollView上之后在修改约束的内容,不然添加的约束会不成,因为系统无法建立他们之间的联系。
self.hiddenConstraint.active = NO;
self.topConstraint.active = YES;
self.bottomConstraint.active = YES;
//等比例的伸缩
CGFloat scale= 1-(offsetY/60);
scale = (scale&=1)?scale :1;
self.topImageView.transform = CGAffineTransformMakeScale(scale, scale);
最后补充:
在子控件的尺寸不能通过UIScrollView来计算,可以通过以下方式计算
设置固定值(width==100,height==300)
相对于UIScrollView以外的其他控件来计算尺寸
在UIScrollView里面布局子控件,sb里面默认是是需要子控件的尺寸以及子控件与UIScrollView之间的间距来计算出scroller的conentSize的。所以这就是上面的子控件要与父控件来等宽的原因了。
UIScrollView的frame应该通过子控件以外的其他控件来计算
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
分享 iOS 开发的知识,解决大家遇到的问题,讨论iOS开发的前沿,欢迎大家投稿~
· 28828人关注
学习从点滴开始 !
(PS: 拒绝部分投稿的文章仅仅是由于专题内已收录相关知识点的文章, 并非是投稿的文章技术含量不够好, 望谅解.)
· 5972人关注
心情不好的时候问自己 :
我为何这么屌
心情好的时候问自己 : 为什么比我屌的这么多
· 3828人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:8767人阅读
ios ui实现及优化(view)(25)
有时候我们会需要在界面上拖动uiview是继承于uiresponder的,所以可以响应触摸相关的事件。
重点是以下一组方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event&
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event&&&& // 触摸事件结束,如果你需要自动把view停靠到一个位置,实现这个方法
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event& //外界因素取消touch事件等,如进入电话,进行特别处理
对于最上面两个方法是必须实现的,后面两个方法是用来做一些额外的需求或者处理使用,如果只是要实现拖动view可以不实现。
思路1: 创建一个uiview(或者你需要的控件)的子类,在类中实现上述的方法。
思路2:在你相应的viewcontroller中实现上述方法(在viewcontroller中持有你要拖动的view,这样才能控制它),也能实现类&#20284;的目的,但这样触摸的范围就会是整个viewcontroller的view,你需要在touchesBegan进行相应的判断(从UITouch中可以得到view的相关信息),才能实现固定在小窗口内部的触摸。
两种思路都是可行的,根据你实际情况去做选择,都没有问题。
以下是代码(子类方式的简单实现,你也可以进行相应修改放到viewcontroller中):
@interface TouchEaglView()
@property (assign, nonatomic) CGP
@implementation TouchEaglView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
&&& UITouch *touch = [touches anyObject];
&&& self.beginpoint = [touch locationInView:self];
&&& [super touchesBegan:touches withEvent:event];
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
&&& UITouch *touch = [touches anyObject];
&&& CGPoint currentLocation = [touch locationInView:self];
&&& CGRect frame = self.
&&& frame.origin.x &#43;= currentLocation.x - self.beginpoint.x;
&&& frame.origin.y &#43;= currentLocation.y - self.beginpoint.y;
&&& self.frame =
上面的代码存在一个问题,那就是他的触摸移动范围包括了屏幕之外,你会发现你可以把view部分拖动到屏幕外部。那么我们需要一个高级一些的实现:
注:这个版本是基于viewcontroller的实现,并未子类化self.localview是你持有的小窗口,beginpoint需要你在viewcontroller中自己定义
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
&&& if (!self.isInView)&&& // 仅当取到touch的view是小窗口时,我们才响应触控,否则直接return
&&& UITouch *touch = [touches anyObject];
&&& CGPoint currentPosition = [touch locationInView:self.localView];
&&& //偏移量
&&& float offsetX = currentPosition.x - beginpoint.x;
&&& float offsetY = currentPosition.y - beginpoint.y;
&&& //移动后的中心坐标
&&& self.localView.center = CGPointMake(self.localView.center.x &#43; offsetX, self.localView.center.y &#43; offsetY);
&&& //x轴左右极限坐标
&&& if (self.localView.center.x & (self.localView.superview.frame.size.width-self.localView.frame.size.width/2))
&&&&&&& CGFloat x = self.localView.superview.frame.size.width-self.localView.frame.size.width/2;
&&&&&&& self.localView.center = CGPointMake(x, self.localView.center.y &#43; offsetY);
&&& else if (self.localView.center.x & self.localView.frame.size.width/2)
&&&&&&& CGFloat x = self.localView.frame.size.width/2;
&&&&&&& self.localView.center = CGPointMake(x, self.localView.center.y &#43; offsetY);
&&& //y轴上下极限坐标
&&& if (self.localView.center.y & (self.localView.superview.frame.size.height-self.localView.frame.size.height/2))
&&&&&&& CGFloat x = self.localView.center.x;
&&&&&&& CGFloat y = self.localView.superview.frame.size.height-self.localView.frame.size.height/2;
&&&&&&& self.localView.center = CGPointMake(x, y);
&&& else if (self.localView.center.y &= self.localView.frame.size.height/2)
&&&&&&& CGFloat x = self.localView.center.x;
&&&&&&& CGFloat y = self.localView.frame.size.height/2;
&&&&&&& self.localView.center = CGPointMake(x, y);
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
&&& UITouch *touch = [touches anyObject];
&&& if (touch.view.frame.size.width == 120)&& // 120为小窗口的宽度(简单起见这里使用硬编码示例),用来判断触控范围;仅当取到touch的view是小窗口时,我们才响应触控
&&&&&&& self.isInView = YES;
&&&&&&& self.isInView = NO;
&&& beginpoint = [touch locationInView:self.localView];
&&& [super touchesBegan:touches withEvent:event];
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:450523次
积分:5630
积分:5630
排名:第3491名
原创:103篇
转载:141篇
评论:110条
(4)(4)(5)(12)(12)(4)(15)(21)(8)(2)(2)(3)(2)(14)(2)(3)(3)(2)(1)(6)(4)(2)(5)(1)(32)(21)(3)(8)(9)(3)(1)(7)(6)(6)(11)(1)(3)(1)(1)(4)iOS如何实现长按拖动控件_iOS开发_
iOS如何实现长按拖动控件
来源:人气:345
  实现控件拖动的方法有多种,可以使用UICollectionView的代理方法直接实现,但是有些开发者在初始时没有使用UICollectionView创建九宫格,后来增加需求,却要增加这种拖动移动的效果,又不想更改页面的初始控件,那么应该怎么实现呢?
  方法很简单,首先在@interface创建以下全局变量;
@interface YRViewController ()
CGPoint startP
CGPoint originP
@operty (strong , nonatomic) NSMutableArray *itemA
  如图所示,在viewDidLoad里创建了如下的控件布局;
1 - (void)viewDidLoad
[super viewDidLoad];
for (NSInteger i = 0;i&8;i++)
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor redColor];
btn.frame = CGRectMake(50+(i%2)*100, 64+(i/2)*100, 90, 90);
btn.titleLabel.font = [UIFont boldSystemFontOfSize:20];
[btn setTitle:[NSString stringWithFormat:@"%d",1+i] forState:UIControlStateNormal];
[self.view addSubview:btn];
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonLongPressed:)];
[btn addGestureRecognizer:longGesture];
[self.itemArray addObject:btn];
  下面,我们就要思考,如何实现长按移动了,控件的移动并且重新排序,主要是考虑移动的那个控件移动到新的位置,直接看下列代码,
1 - (void)buttonLongPressed:(UILongPressGestureRecognizer *)sender
UIButton *btn = (UIButton *)sender.
if (sender.state == UIGestureRecognizerStateBegan)
startPoint = [sender locationInView:sender.view];
originPoint = btn.
[UIView animateWithDuration:Duration animations:^{
btn.transform = CGAffineTransformMakeScale(1.1, 1.1);
btn.alpha = 0.7;
else if (sender.state == UIGestureRecognizerStateChanged)
CGPoint newPoint = [sender locationInView:sender.view];
CGFloat deltaX = newPoint.x-startPoint.x;
CGFloat deltaY = newPoint.y-startPoint.y;
btn.center = CGPointMake(btn.center.x+deltaX,btn.center.y+deltaY);
//NSLog(@"center = %@",NSStringFromCGPoint(btn.center));
NSInteger index = [self indexOfPoint:btn.center withButton:btn];
if (index&0)
contain = NO;
[UIView animateWithDuration:Duration animations:^{
CGPoint temp = CGPointZ
UIButton *button = _itemArray[index];
temp = button.
button.center = originP
btn.center =
originPoint = btn.
contain = YES;
else if (sender.state == UIGestureRecognizerStateEnded)
[UIView animateWithDuration:Duration animations:^{
btn.transform = CGAffineTransformI
btn.alpha = 1.0;
if (!contain)
btn.center = originP
  下面这个方法用来判断要移动的button将要移动到的位置的center是不是在button数组(itemArray)元素的位置中,如果是,返回i 新位置原来的button是数组中得第几个元素,否则,返回-1。
1 - (NSInteger)indexOfPoint:(CGPoint)point withButton:(UIButton *)btn
for (NSInteger i = 0;i&_itemArray.i++)
UIButton *button = _itemArray[i];
if (button != btn)
if (CGRectContainsPoint(button.frame, point))
return -1;
  这样,我们通过位置判断,让控件的位置得以改变。
优质网站模板}

我要回帖

更多关于 不喜欢ios10 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信