preface
Knowledge is endless, and skills need to be accumulated, recorded bit by bit, to enrich the timeline of growth. Today is about UITableView/UICollectionView some use skills. Develop it according to your own project situation.
Header/Footer height and hover Settings
Height setting
Sometimes we need to set the distance between the head and the tail of the TableView, and the height of the head and tail just needs to be set in the proxy.
Example code is as follows:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0.01f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, kScreenWidth, 20)];
view.backgroundColor = [UIColor clearColor];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 10;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, kScreenWidth, 1)];
view.backgroundColor = [UIColor clearColor];
return view;
}
Copy the code
Summary: As you can see from the code above, when you customize the header and tail views, even if the height is set for the custom header and tail views. Highly eventually by the tableView: heightForHeaderInSection: and tableView: heightForFooterInSection: two proxy method. When these two proxy methods are not implemented, the height is the default height.
hover
The hover function for tableViews is only available if the Style is UITableViewStylePlain. If there’s a requirement, you need to have a Header hover, and you need to have a space between sections. The effect is as follows:
Method one (all hover) :
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return kHeaderHeight+9;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
BillListModel *model = _sectionArr[section];
UIView *header = ({
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0.0, KScreenWidth, kHeaderHeight+9)];
bgView.backgroundColor = [UIColorTools colorWithTheme:UIColorThemeAppBgColor];
UILabel *titleLab = [[UILabel alloc] initWithFrame:CGRectMake(0.9, KScreenWidth, kHeaderHeight)];
titleLab.backgroundColor = [UIColorTools colorWithTheme:UIColorThemeWhite];
titleLab.textColor = [UIColorTools colorWithTheme:UIColorThemeBlack];
titleLab.text = model.time;
[bgView addSubview:titleLab];
UIImageView *lineHBottom = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, titleLab.mj_max_y - 0.5, KScreenWidth, 0.5)];
lineHBottom.backgroundColor = [UIColorTools colorWithTheme:UIColorThemeSeparatorColor];
[bgView addSubview:lineHBottom];
bgView;
});
return header;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == _tableView) {
UITableView *tableview = (UITableView *)scrollView;
CGFloat sectionHeaderHeight = kHeaderHeight;
CGFloat sectionFooterHeight = 9;
CGFloat offsetY = tableview.contentOffset.y;
if (offsetY >= 0 && offsetY <= sectionFooterHeight) {
tableview.contentInset = UIEdgeInsetsMake(-offsetY, 0, -sectionHeaderHeight, 0);
} else if (offsetY >= sectionFooterHeight && offsetY <= tableview.contentSize.height - tableview.frame.size.height - sectionHeaderHeight) {
tableview.contentInset = UIEdgeInsetsMake(-sectionFooterHeight, 0.0.0);
} else if (offsetY >= 0 && tableview.contentSize.height >= tableview.contentSize.height) {
tableview.contentInset = UIEdgeInsetsMake(-sectionFooterHeight, 0.0.0); }}}Copy the code
Mode 2 (partial hovering) :
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == 0) {
return 10.f;
} else if (section == 2) {
return 0;
}
return kHeight4_7(35);
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 10.f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [UIView new];
headerView.backgroundColor = [UIColorTools colorWithTheme:UIColorThemeWhite];
if (section == 0) {
headerView.backgroundColor = [UIColor clearColor];
}
return headerView;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *footerView = [[UIView alloc] init];
footerView.backgroundColor = [UIColor clearColor];
return footerView;
}
Copy the code
The hovering function of the CollectionView is only available if the Style is UITableViewStylePlain. If there’s a requirement, you need to have a Header hover, and you need to have a space between sections. The effect is as follows:
Scroll to monitor
UIScrollView deceleration
Activity Rate, which is in the range (0.0, 1.0), will slow down when the activity goes up with a touch rate of 0.1.
How does UIScrollView decide to stop sliding
To be clear, there are two ways to stop sliding:
1. The first is to stop the ScrollView with your finger.
When the finger stops swiping, iOS adjusts the UIScrollView’s delegate
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
Copy the code
Activity, if it’s still NO, it’s going to stop, otherwise it’s not going to stop
2, the second is that ScrollView stops sliding, refers to the scrollbar completely stopped down.
Activity. When Activity ate = True, iOS will adjust the UIScrollView’s delegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
Copy the code
UIScrollView actually stops sliding. Solutions are as follows:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if(! decelerate) {//OK, really stop doing something}}/ / then
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
//OK, really stop doing something
}
Copy the code
UIScrollView does not allow you to slide left or right when you swipe left or right
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat contentOffsetX = scrollView.contentOffset.x;
if (contentOffsetX<=0 || contentOffsetX>=kScreenWidth) {
// When sliding to the left or right, no further sliding is allowed
scrollView.scrollEnabled = NO;
} else {
scrollView.scrollEnabled = YES; }} - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
scrollView.scrollEnabled = YES;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
scrollView.scrollEnabled = YES;
}
Copy the code
The messaging
When a finger is touched, the scrollView will temporarily intercept the touch event, using a timer. If no finger movement event occurs after the timer expires, the scrollView will send tracking Events to the clicked subView. If a movement event occurs before the timer expires, the scrollView unrolls tracking by itself.
Subclasses can override touchesShouldBegin: withEvent: inContentView: decide whether they receive touch events. When pagingEnabled is set to YES, it scrolls automatically to the subView boundary, default is NO.
TouchesShouldCancelInContentView: start sending tracking messages message to call this method when subView, decide whether to send tracking messages message to a subView, if return NO, is to send, YES Indicates that the packet is not sent.
If canCancelContentTouches is NO, this method is not called to affect how scrolling gestures are handled.
Modify the position of headerView in tableView (similar to meituan takeout home page)
Set scrollView.contentInset to scrollView.contentInset
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat contentOffsety = scrollView.contentOffset.y;
_contentOffSet_y = contentOffsety;
// This header is actually the distance from the header of the section to the top
CGFloat header = kBannerHight+[HSFuntionCell cellHeight]+kFooterViewHeight- 64.;
NSLog(@"=======%lf=====%lf", contentOffsety, header);
if (contentOffsety<=header&&contentOffsety>=0) {
// When the view slides less than the header
scrollView.contentInset = UIEdgeInsetsMake(0.0.0.0);
self.headerView.layer.borderColor = [UIColorTools colorWithTheme:UIColorThemeWhite].CGColor;
} else if (contentOffsety>header) {
// Set the position of the header of the section when the distance of the view is greater than the header, taking into account the transparency of the navigation bar on the scrolling view
scrollView.contentInset = UIEdgeInsetsMake(64.0.0.0);
self.headerView.layer.borderColor = [UIColorTools colorWithTheme:UIColorThemeSeparatorColor].CGColor;
}
self.headerView.borderWhich = DDViewBorderTop;
// Set the navigation bar transparency
[self setNavigationColor:contentOffsety];
}
Copy the code
Top stretching effect (head stretching)
Implement idea: a custom ViewA, as a TableView headerView, and then listen to the TableView scroll, pass the callback to ViewA can.
The effect is as follows:
Below is a custom MOActivityTopView
.h files
@interface MOActivityTopView : UIView
@property (nonatomic.strong) MOActivityModel *model;
- (void)didScroll:(CGFloat)contentOffSetY;
@end
Copy the code
.m files
#import "MOActivityTopView.h"
#define kViewHeight (kScreenWidth*340/750.)
#define kTopHeight (kScreenWidth*240/750.)
#define kBottomHeight (kScreenWidth*100/750.)
@interface MOActivityTopView(a)
/ / / background
@property (nonatomic.strong) UIImageView *backgroundImgV;
/ / / frosted glass
@property (nonatomic.strong) UIVisualEffectView *visualEffectView;
/ / / the activity diagram
@property (nonatomic.strong) UIImageView *activityImgV;
/// Activity name
@property (nonatomic.strong) UILabel *activityLab;
@end
@implementation MOActivityTopView
- (instancetype)init {
if (self = [super initWithFrame:CGRectMake(0.0, kScreenWidth, kViewHeight)]) {
[self setUp];
}
return self;
}
#pragma mark - Getter- (UIImageView *)backgroundImgV {
if (_backgroundImgV == nil) {
_backgroundImgV = [[UIImageView alloc]initWithFrame:CGRectMake(0.0.self.dd_w, kTopHeight)];
[_backgroundImgV setContentMode:UIViewContentModeScaleAspectFill];
[_backgroundImgV setClipsToBounds:YES];
}
return _backgroundImgV;
}
- (void)setUp {
[self addSubview:self.backgroundImgV];
UIVisualEffect *blurEffect;
blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
_visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
/ / _visualEffectView. Alpha = 0.8;
_visualEffectView.frame = self.backgroundImgV.frame;
[self addSubview:_visualEffectView];
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0.self.backgroundImgV.dd_max_y, kScreenWidth, kBottomHeight)];
bgView.backgroundColor = [UIColorTools colorWithTheme:UIColorThemeWhite];
[self addSubview:bgView];
CGFloat height = (kScreenWidth*160/750.);
CGFloat width = height/(16/21.);
_activityImgV = [[UIImageView alloc] initWithFrame:CGRectMake(15, bgView.dd_h7 --height, width, height)];
[bgView addSubview:_activityImgV];
_activityLab = [[UILabel alloc] initWithFrame:CGRectMake(_activityImgV.dd_max_x+8.0, kScreenWidth-_activityImgV.dd_max_x- 8 -- 15, kBottomHeight)];
_activityLab.textColor = [UIColorTools colorWithTheme:UIColorThemeBlack];
_activityLab.numberOfLines = 2;
// _activityLab.adjustsFontSizeToFitWidth = YES;
[bgView addSubview:_activityLab];
}
- (void)layoutSubviews {
[super layoutSubviews];
_activityImgV.clipsToBounds = YES;
_activityImgV.layer.masksToBounds = YES;
_activityImgV.layer.borderWidth = 1.5;
_activityImgV.layer.borderColor = [UIColorTools colorWithTheme:UIColorThemeWhite].CGColor;
_activityImgV.layer.cornerRadius = kViewCornerRadius;
}
- (void)setModel:(MOActivityModel *)model {
_model = model;
[_activityImgV sd_setImageWithURL:kMOImageUrlSet(model.ActivityURL) placeholderImage:[UIImage placeholderImage_activity]];
[_backgroundImgV sd_setImageWithURL:kMOImageUrlSet(model.ActivityURL) placeholderImage:kImageSet(@"Icon-noti")];
_activityLab.text = model.ActivityName;
}
- (void)didScroll:(CGFloat)contentOffSetY {
// Image height
CGFloat imageHeight = self.dd_h;
// Image width
CGFloat imageWidth = kScreenWidth;
// The upper and lower offsets of the image
CGFloat imageOffsetY = contentOffSetY;
// NSLog(@" imageOffsetY:%f ->",imageOffsetY);
/ / the drop-down
if (imageOffsetY < 0) {
CGFloat totalOffset = imageHeight + ABS(imageOffsetY);
CGFloat f = totalOffset / imageHeight;
self.backgroundImgV.frame = CGRectMake(-(imageWidth * f - imageWidth) * 0.5, imageOffsetY, imageWidth * f, totalOffset);
}
/ / / /
// if (imageOffsetY > 0) {
// CGFloat totalOffset = imageHeight - ABS(imageOffsetY);
// CGFloat f = totalOffset / imageHeight;
// [self.backgroundImgV setFrame:CGRectMake(-(imageWidth * f - imageWidth) * 0.5, imageOffsetY, imageWidth * f, totalOffset)];
/ /}
_visualEffectView.frame = self.backgroundImgV.frame;
}
@end
Copy the code
Monitor the scroll
- (UIView *)topHeaderView {
if(! _topHeaderView) { _topHeaderView = [[MOActivityTopView alloc] init]; _topHeaderView.model = _model; }return _topHeaderView;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat contentOffSetY = scrollView.contentOffset.y;
[self.topHeaderView didScroll:contentOffSetY];
}
Copy the code
Thank you again for taking the time to read this article!
Weibo: @danny_ Lu Changhui blog: SuperDanny