DZNEMpty DataSet의 이해 노트
UIScrollView+EmptyDataSet에 대한 해독1.
UIScrollView+EmptyDataSet.h 파일은 DZNEmptyDataSetSource와 DZNEmptyDataSetDelegate 프로토콜에서 대량의 방법을 제공했고 세 가지 속성과 하나의 공유 방법을 제공했다.emptyDataSetSource;emptyDataSetDelegate ;emptyDataSetVisible;-(void)reloadEmptyDataSet( empty )
둘째,
UIScrollView+EmptyDataSet.m 파일에서 세 가지 유형의 실현을 제공하였다.1,
UIView+DZNConstraintBasedLayoutExtensions는 다음과 같은 방법 하나만 제공했다.제약을 실현하는 데 쓰다- (NSLayoutConstraint *)equallyRelatedConstraintWithView:(UIView *)view attribute:(NSLayoutAttribute)attribute
{
return [NSLayoutConstraint constraintWithItem:view
attribute:attribute
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:attribute
multiplier:1.0
constant:0.0];
}
2,
DZNWeakObjectContainer : NSObject 하나의 방법과 속성만 제공한다.아래와 같다@interface DZNWeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id weakObject;
- (instancetype)initWithWeakObject:(id)object;
@end
@implementation DZNWeakObjectContainer
- (instancetype)initWithWeakObject:(id)object
{
self = [super init];
if (self) {
_weakObject = object;
}
return self;
}
@end
3,
DZNEmptyDataSetView : UIView @interface DZNEmptyDataSetView : UIView
@property (nonatomic, readonly) UIView *contentView;
@property (nonatomic, readonly) UILabel *titleLabel;
@property (nonatomic, readonly) UILabel *detailLabel;
@property (nonatomic, readonly) UIImageView *imageView;
@property (nonatomic, readonly) UIButton *button;
@property (nonatomic, strong) UIView *customView;
@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;
@property (nonatomic, assign) CGFloat verticalOffset;
@property (nonatomic, assign) CGFloat verticalSpace;
@property (nonatomic, assign) BOOL fadeInOnDisplay;
- (void)setupConstraints;
- (void)prepareForReuse;
@end
// didMoveToSuperView
- (void)didMoveToSuperview
{
self.frame = self.superview.bounds;
void(^fadeInBlock)(void) = ^{_contentView.alpha = 1.0;};
if (self.fadeInOnDisplay) {
[UIView animateWithDuration:0.25
animations:fadeInBlock
completion:NULL];
}
else {
fadeInBlock();
}
}
/***
,
***/
// ;
- (void)didTapButton:(id)sender
{
SEL selector = NSSelectorFromString(@"dzn_didTapDataButton:");
if ([self.superview respondsToSelector:selector]) {
[self.superview performSelector:selector withObject:sender afterDelay:0.0f];
}
}
// , HVL ,
- (void)setupConstraints
{
// First, configure the content view constaints
// The content view must alway be centered to its superview
NSLayoutConstraint *centerXConstraint = [self equallyRelatedConstraintWithView:self.contentView attribute:NSLayoutAttributeCenterX];
NSLayoutConstraint *centerYConstraint = [self equallyRelatedConstraintWithView:self.contentView attribute:NSLayoutAttributeCenterY];
[self addConstraint:centerXConstraint];
[self addConstraint:centerYConstraint];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:nil views:@{@"contentView": self.contentView}]];
// When a custom offset is available, we adjust the vertical constraints' constants
if (self.verticalOffset != 0 && self.constraints.count > 0) {
centerYConstraint.constant = self.verticalOffset;
}
// If applicable, set the custom view's constraints
if (_customView) {
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[customView]|" options:0 metrics:nil views:@{@"customView":_customView}]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[customView]|" options:0 metrics:nil views:@{@"customView":_customView}]];
}
else {
CGFloat width = CGRectGetWidth(self.frame) ? : CGRectGetWidth([UIScreen mainScreen].bounds);
CGFloat padding = roundf(width/16.0);
CGFloat verticalSpace = self.verticalSpace ? : 11.0; // Default is 11 pts
NSMutableArray *subviewStrings = [NSMutableArray array];
NSMutableDictionary *views = [NSMutableDictionary dictionary];
NSDictionary *metrics = @{@"padding": @(padding)};
// Assign the image view's horizontal constraints
if (_imageView.superview) {
[subviewStrings addObject:@"imageView"];
views[[subviewStrings lastObject]] = _imageView;
[self.contentView addConstraint:[self.contentView equallyRelatedConstraintWithView:_imageView attribute:NSLayoutAttributeCenterX]];
}
// Assign the title label's horizontal constraints
if ([self canShowTitle]) {
[subviewStrings addObject:@"titleLabel"];
views[[subviewStrings lastObject]] = _titleLabel;
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(padding@750)-[titleLabel(>=0)]-(padding@750)-|"
options:0 metrics:metrics views:views]];
}
// or removes from its superview
else {
[_titleLabel removeFromSuperview];
_titleLabel = nil;
}
// Assign the detail label's horizontal constraints
if ([self canShowDetail]) {
[subviewStrings addObject:@"detailLabel"];
views[[subviewStrings lastObject]] = _detailLabel;
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(padding@750)-[detailLabel(>=0)]-(padding@750)-|"
options:0 metrics:metrics views:views]];
}
// or removes from its superview
else {
[_detailLabel removeFromSuperview];
_detailLabel = nil;
}
// Assign the button's horizontal constraints
if ([self canShowButton]) {
[subviewStrings addObject:@"button"];
views[[subviewStrings lastObject]] = _button;
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(padding@750)-[button(>=0)]-(padding@750)-|"
options:0 metrics:metrics views:views]];
}
// or removes from its superview
else {
[_button removeFromSuperview];
_button = nil;
}
NSMutableString *verticalFormat = [NSMutableString new];
// Build a dynamic string format for the vertical constraints, adding a margin between each element. Default is 11 pts.
for (int i = 0; i < subviewStrings.count; i++) {
NSString *string = subviewStrings[i];
[verticalFormat appendFormat:@"[%@]", string];
if (i < subviewStrings.count-1) {
[verticalFormat appendFormat:@"-(%.f@750)-", verticalSpace];
}
}
// Assign the vertical constraints to the content view
if (verticalFormat.length > 0) {
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|%@|", verticalFormat]
options:0 metrics:metrics views:views]];
}
}
}
4,
UIScrollView+DZNEmptyDataSet 모든 관건은 아래 코드에서 swizzle의 사용으로 -dzn_reloadData injectreloadData와 endUpdates에서 하면 됩니다.- (void)setEmptyDataSetSource:(id)datasource
{
if (!datasource || ![self dzn_canDisplay]) {
[self dzn_invalidate];
}
objc_setAssociatedObject(self, kEmptyDataSetSource, [[DZNWeakObjectContainer alloc] initWithWeakObject:datasource], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// We add method sizzling for injecting -dzn_reloadData implementation to the native -reloadData implementation
[self swizzleIfPossible:@selector(reloadData)];
// Exclusively for UITableView, we also inject -dzn_reloadData to -endUpdates
if ([self isKindOfClass:[UITableView class]]) {
[self swizzleIfPossible:@selector(endUpdates)];
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.