有個需求是這樣的矿微,有一個lable在一個button點擊后座慰,內(nèi)容發(fā)生改變仑氛,相關(guān)尺寸也要發(fā)生改變坝疼,想要那個點擊的buton位置跟隨lable的位置發(fā)生同步變化搜贤。
開始的思路是在button點擊執(zhí)行的方法中更新相關(guān)約束,位置更新的沒有達(dá)到想要的效果钝凶。就是lable的text屬性改變后仪芒,button的位置約束就更新了,而現(xiàn)在的lable的bounds還沒有變化,或者變化沒有完成掂名。這樣button相對的更新的位置就是沒有完全更新完的lable的位置為基準(zhǔn)据沈。所以沒有達(dá)到效果。
這個時候想著換用添加觀察者模式饺蔑,當(dāng)lable的bounds發(fā)生改變后锌介,button的相對約束再更新。由于lable是系統(tǒng)空間膀钠,不方便直接增加功能掏湾。我這邊選擇一個比較好實現(xiàn)的方式,從新創(chuàng)建一個類繼承自UILable肿嘲,在自定義lable初始化的方式中添加觀察者融击,觀察bounds屬性的變化,這時候效果達(dá)到了要求雳窟。下面是相關(guān)代碼實現(xiàn):
在實現(xiàn)上面的想法使用了block作為屬性尊浪,因為功能單一,使用delegate有點大材小用封救,也不方便拇涤。
***** MyLable.h文件 *****
#import <UIKit/UIKit.h>
@interface MyLable : UILabel
//下面定義了block屬性,確定當(dāng)lable的bounds屬性發(fā)生改變后將要做什么操作
@property (nonatomic,copy) void (^change)();
@end
***** MyLable.m文件 *****
#import "MyLable.h"
@implementation MyLable
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
//稍微對標(biāo)簽做了下美化誉结,有圓角
self.layer.cornerRadius = 5;
self.layer.masksToBounds = YES;
//添加對bounds屬性的觀察
[self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew||NSKeyValueChangeOldKey context:nil];
}
//實現(xiàn)觀察者模式需要實現(xiàn)的方法鹅士,調(diào)用改變后定義的block屬性,做到改變后惩坑,
//完成需要的相關(guān)動作
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
self.change();
NSLog(@"%@",change);
}
//注意在這個方法中移除觀察者掉盅,不然會發(fā)生錯誤。
-(void)dealloc{
[self removeObserver:self forKeyPath:@"bounds"];
}
@end
下面是viewController.m
方法
//中間約束使用了Masonry第三方庫以舒,比較方便趾痘。可以使用cocopods導(dǎo)入到項目中使用蔓钟。
#import "ViewController.h"
#import <Masonry/Masonry.h>
#import "MyLable.h"
@interface ViewController ()
//因為需要在更新位置永票,使用到控件,便放到屬性滥沫,方便使用
@property (nonatomic,strong)MyLable* lb;
@property (nonatomic,strong)UIButton* bt;
//這個是為了點擊后侣集,有不同的效果,設(shè)置的一個變量
@property (nonatomic) BOOL ag;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.ag = YES;
MyLable* lable = [[MyLable alloc]init];
lable.lineBreakMode = NSLineBreakByWordWrapping;
lable.numberOfLines = 0;
lable.text = @"這世界很復(fù)雜,混淆我想說的話我不懂,太復(fù)雜的玩法兰绣,什么樣的禮物肚吏,能夠永遠(yuǎn)記得住讓幸福別走的太倉促,云和天,蝶和花狭魂,從來不需要說話,斷不了依然日夜?fàn)繏斐楦?說情話,只想讓你聽清楚雌澄,我愛你是唯一的傾訴";
lable.font = [UIFont systemFontOfSize:18];
lable.textColor = [UIColor redColor];
lable.backgroundColor = [UIColor grayColor];
self.lb = lable;
float scw = [[UIScreen mainScreen]bounds].size.width;
[self.view addSubview:lable];
[self.lb mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(40);
make.width.mas_equalTo(scw-scw/4);
make.centerX.mas_equalTo(0);
}];
//用這個方法實現(xiàn)button的添加斋泄,可以達(dá)到在lable完成之后,button的相對位置才能正確镐牺。
[self performSelectorOnMainThread:@selector(addButton) withObject:nil waitUntilDone:NO];
}
-(void)addButton{
UIButton* button =[UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:@"點擊" forState:UIControlStateNormal];
//為button添加點擊響應(yīng)方法炫掐,在響應(yīng)方法中確定約束更新。
[button addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor grayColor];
self.bt = button;
self.bt.titleLabel.textColor = [UIColor blackColor];
//避免循環(huán)引用的問題睬涧,為我自定義的MyLable對象的block屬性實現(xiàn)方法募胃。
__block typeof(self) weakself = self;
self.lb.change = ^(){
[weakself.bt mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.lb.bounds.size.height+50);
make.centerX.mas_equalTo(0);
}];
};
self.bt.layer.cornerRadius = 10;
self.bt.layer.masksToBounds = YES;
[self.view addSubview:button];
[button mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.lb.bounds.size.height+50);
make.width.mas_equalTo(100);
make.centerX.mas_equalTo(0);
}];
}
-(void)click{
self.ag = !self.ag;
if (self.ag) {
self.lb.text = @"我是第二個內(nèi)容,我已經(jīng)變化了";
}else{
self.lb.text = @"啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢噢uuuuuuuuuuuuuuuuuuuuuuuuuuuu";
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
好了畦浓,到這里痹束,這個需求已經(jīng)能滿足了。其他更好的辦法還沒有想到讶请,想到了再更新祷嘶,如果有哪個高手有更好的方式,可以給我留言夺溢。