
1:实现头部这种类别滚动的效果

其主要代码如下:
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, screen_width, 40)];
scrollView.pagingEnabled = NO;
scrollView.alwaysBounceHorizontal = YES;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.backgroundColor = RGB(246, 246, 246);
[self.view addSubview:scrollView];
float btnWidth = 60;
for (int i = 0; i < self.cateNameArray.count; i++) {
UIButton *nameBtn = [UIButton buttonWithType:UIButtonTypeCustom];
nameBtn.frame = CGRectMake(btnWidth*i, 0, btnWidth, 40);
nameBtn.tag = 10+i;
nameBtn.font = [UIFont systemFontOfSize:13];
[nameBtn setTitle:self.cateNameArray[i] forState:UIControlStateNormal];
[nameBtn setTitleColor:navigationBarColor forState:UIControlStateSelected];
[nameBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[nameBtn addTarget:self action:@selector(OnTapNameBtn:) forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:nameBtn];
if (i == 0) {
// nameBtn.selected = YES;
_lineView = [[UIView alloc] initWithFrame:CGRectMake(nameBtn.center.x-20, 38, 40, 2)];
_lineView.backgroundColor = navigationBarColor;
[scrollView addSubview:_lineView];
}
}
scrollView.contentSize = CGSizeMake(self.cateNameArray.count*btnWidth, 0);
-(void)OnTapNameBtn:(UIButton *)sender{
NSInteger index = sender.tag - 10;
if (index == _currentIndex) {
return;
}
_currentIndex = index;
_cateid = _cateIDArray[index];
_page = 1;
[UIView animateWithDuration:0.5 animations:^{
_lineView.center = CGPointMake(sender.center.x, 39);
}];
//刷新数据
[self.tableView.gifHeader beginRefreshing];
}
其中_lineView是一个view,因为这边还有滚动时刷新底下的列表;
2:另外一种使用第三方的插件XTSegmentControl,结合iCarousel进行滚动选项卡
效果如下:
![]() |
![]() |
主要代码如下:
#import <UIKit/UIKit.h> #import "oldChildVewController.h" #import "ChildViewController.h" #import "newChildVewController.h" #import "XTSegmentControl.h" #import "iCarousel.h" #import "Masonry.h" @interface ViewController : UIViewController<iCarouselDataSource, iCarouselDelegate> @end
#import "ViewController.h"
#define kScreen_Height [UIScreen mainScreen].bounds.size.height
#define kScreen_Width [UIScreen mainScreen].bounds.size.width
#define kMySegmentControl_Height 44.0
@interface ViewController ()
@PRoperty (strong, nonatomic) NSMutableDictionary *myProActivitiesDict;
@property (strong, nonatomic) XTSegmentControl *mySegmentControl;
@property (strong, nonatomic) NSArray *titlesArray;
@property (strong, nonatomic) iCarousel *myCarousel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor whiteColor];
CGRect frame=self.view.bounds;
self.myCarousel = ({
iCarousel *icarousel = [[iCarousel alloc] initWithFrame:frame];
icarousel.dataSource = self;
icarousel.delegate = self;
icarousel.decelerationRate = 1.0;
icarousel.scrollSpeed = 1.0;
icarousel.type = iCarouselTypeLinear;
icarousel.pagingEnabled = YES;
icarousel.clipsToBounds = YES;
icarousel.bounceDistance = 0.2;
[self.view addSubview:icarousel];
[icarousel mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).insets(UIEdgeInsetsMake(kMySegmentControl_Height, 0, 0, 0));
}];
icarousel;
});
//添加滑块
__weak typeof(_myCarousel) weakCarousel = _myCarousel;
self.mySegmentControl = [[XTSegmentControl alloc] initWithFrame:CGRectMake(0, 0, kScreen_Width, kMySegmentControl_Height) Items:self.titlesArray selectedBlock:^(NSInteger index) {
[weakCarousel scrollToItemAtIndex:index animated:NO];
}];
[self.view addSubview:self.mySegmentControl];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Getter/Setter
- (NSArray*)titlesArray
{
if (nil == _titlesArray) {
_titlesArray = @[@"全部", @"任务", @"讨论", @"文档", @"代码", @"其他"];
}
return _titlesArray;
}
#pragma mark iCarousel M
- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel{
return [self.titlesArray count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{
UIViewController *childContrll;
switch (index) {
case 0:
{
childContrll=[[ChildViewController alloc]init];
break;
}
case 1:
{
childContrll=[[oldChildVewController alloc]init];
break;
}
default:
childContrll=[[newChildVewController alloc]init];
break;
}
return childContrll.view;
}
- (void)carouselDidScroll:(iCarousel *)carousel{
if (_mySegmentControl) {
float offset = carousel.scrollOffset;
if (offset > 0) {
[_mySegmentControl moveIndexWithProgress:offset];
}
}
}
- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel{
if (_mySegmentControl) {
_mySegmentControl.currentIndex = carousel.currentItemIndex;
}
}
@end
您也可以通过这边进行代码下载:源代码下载
补充1:上面我们是不让它出现滚动的,只在一个屏幕的宽度里进行排列,假如有多个时就要出现可以滚动的,可以针对XTSegmentControl.m进行修改,主要修改地方如下:

#define XTSegmentControlHspace (12)
- (void)initItemsWithTitleArray:(NSArray *)titleArray
{
_itemFrames = @[].mutableCopy;
_items = @[].mutableCopy;
float y = 0;
float height = CGRectGetHeight(self.bounds);
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:XTSegmentControlItemFont]};
NSObject *obj = [titleArray firstObject];
if ([obj isKindOfClass:[NSString class]]) {
for (int i = 0; i < titleArray.count; i++) {
NSString *title = titleArray[i];
CGSize size = [title sizeWithAttributes:attributes];
float x = i > 0 ? CGRectGetMaxX([_itemFrames[i-1] CGRectValue]) : 0;
float width = 2 * XTSegmentControlHspace + size.width;
CGRect rect = CGRectMake(x, y, width, height);
[_itemFrames addObject:[NSValue valueWithCGRect:rect]];
}
for (int i = 0; i < titleArray.count; i++) {
CGRect rect = [_itemFrames[i] CGRectValue];
NSString *title = titleArray[i];
XTSegmentControlItem *item = [[XTSegmentControlItem alloc] initWithFrame:rect title:title type:XTSegmentControlItemTypeTitle];
if (i == 0) {
[item setSelected:YES];
}
[_items addObject:item];
[_contentView addSubview:item];
}
}
[_contentView setContentSize:CGSizeMake(CGRectGetMaxX([[_itemFrames lastObject] CGRectValue]), CGRectGetHeight(self.bounds))];
self.currentIndex = 0;
[self selectIndex:0];
}
- (void)addRedLine
{
if (!_lineView) {
CGRect rect = [_itemFrames[0] CGRectValue];
_lineView = [[UIView alloc] initWithFrame:CGRectMake(XTSegmentControlHspace, CGRectGetHeight(rect) - XTSegmentControlLineHeight, CGRectGetWidth(rect) - 2 * XTSegmentControlHspace, XTSegmentControlLineHeight)];
_lineView.backgroundColor = [UIColor colorWithHexString:@"0x3bbd79"];
[_contentView addSubview:_lineView];
UIView *bottomLineView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(rect)-0.5, CGRectGetWidth(self.bounds), 0.5)];
bottomLineView.backgroundColor = [UIColor colorWithHexString:@"0xc8c7cc"];
[self addSubview:bottomLineView];
}
}
补充2:当下面部分在手动划动时,如果菜单不在当前屏幕时,那它就不法跟随滚动到当前菜单的位置,同样对它进行简单的修改;
XTSegmentControl.h(把- (void)setScrollOffset:(NSInteger)index放出来让外面的进行调用)
@interface XTSegmentControl : UIView @property (nonatomic) NSInteger currentIndex; - (instancetype)initWithFrame:(CGRect)frame Items:(NSArray *)titleItem delegate:(id <XTSegmentControlDelegate>)delegate; - (instancetype)initWithFrame:(CGRect)frame Items:(NSArray *)titleItem selectedBlock:(XTSegmentControlBlock)selectedHandle; - (void)selectIndex:(NSInteger)index; - (void)moveIndexWithProgress:(float)progress; - (void)endMoveIndex:(NSInteger)index; - (void)setScrollOffset:(NSInteger)index; @end
然后外面icarousel结合时调用进行简单修改(主要是这一行[_mySegmentControl setScrollOffset:index]):
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{
[_mySegmentControl setScrollOffset:index];
UIViewController *childContrll;
switch (index) {
case 0:
{
childContrll=[[ChildViewController alloc]init];
break;
}
case 1:
{
childContrll=[[oldChildVewController alloc]init];
break;
}
default:
childContrll=[[newChildVewController alloc]init];
break;
}
return childContrll.view;
}
修改后的代码下载地址:源代码下载
3:几个不错的实例
a: https://github.com/HAHAKea/HACursor

b: https://github.com/fergusding/FDSlideBar
