【问题标题】:IOS Custom Segmented Pager -Make Indicator Scroll instead of tabIOS 自定义分段寻呼机 - 使指示器滚动而不是选项卡
【发布时间】:2015-10-21 07:27:43
【问题描述】:

我正在尝试为客户编写此设计(主要关注顶部选项卡寻呼机,也称为选项卡 A、选项卡 B、选项卡 C): 我们能找到的最接近的骨架起点是:https://github.com/HusseinB/HBPageViewController

唯一的问题是在这个寻呼机中,当您滑动而不是顶部指示器时,标签会滚动,并且我在如何进行转换时画了一个空白。我知道答案可能与我们只需要 3 个标签和目标是让黄色指示器根据您所在的页面移动,同时标签保持静止。

#import "HBPageViewController.h"

#define degreesToRadians( degrees ) ( ( degrees ) / 180.0 * M_PI )

@interface HBPageViewController () <UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate, UIViewControllerTransitioningDelegate>
@property (nonatomic, strong) UIPageViewController *pageViewController;
@property (nonatomic, strong) UIScrollView *picker;
@property (nonatomic, strong) UIViewController* parent;
@end

@implementation HBPageViewController{
    NSInteger currentSelectedPickerButton;
    float startingPageScrollViewContentOffsetX;
    BOOL gestureDrivenTransition;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (id)initWithParentViewController:(UIViewController *)parent{
    self = [super init];

    if (self) {
        _parent = parent;
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSLog(@"PICKER_HEIGHT: %f", _pickerHeight);
    if (_parent.navigationController.navigationBar.translucent) {
        [self.view setFrame:CGRectMake(0, 64+_pickerHeight, _parent.view.frame.size.width, _parent.view.frame.size.height-64-_pickerHeight)];
    } else{
        [self.view setFrame:CGRectMake(_parent.view.frame.origin.x, _pickerHeight, _parent.view.frame.size.width, _parent.view.frame.size.height-_pickerHeight)];
    }

    [self createPicker];

    [self createPageViewController];
}

- (void)createPicker{
    if (_pickerHeight) {
        _picker = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, _pickerHeight)];
    } else{
        _picker = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 30)];
    }

    for (UIViewController* vc in _viewControllers) {
        float pickerButtonWidth = self.view.frame.size.width/3;
        float pickerButtonHeight = _picker.frame.size.height;
        NSUInteger currentVCIndex = [_viewControllers indexOfObject:vc];
        UIButton *pickerButton = [[UIButton alloc] initWithFrame:CGRectMake(pickerButtonWidth*currentVCIndex, 0, pickerButtonWidth, pickerButtonHeight)];
        [pickerButton setTitle:vc.title forState:UIControlStateNormal];
        [pickerButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
        [pickerButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
        if (_pickerButtonNormalTitleColor) {
            [pickerButton setTitleColor:_pickerButtonNormalTitleColor forState:UIControlStateNormal];
        }
        if (_pickerButtonSelectedTitleColor) {
            [pickerButton setTitleColor:_pickerButtonSelectedTitleColor forState:UIControlStateSelected];
        }
        if (_pickerButtonTitleFont) {
            [pickerButton.titleLabel setFont:_pickerButtonTitleFont];
        }
        if (_pickerButtonTintColor) {
            [pickerButton setTintColor:_pickerButtonTintColor];
        }

        [pickerButton setTag:currentVCIndex];
        [pickerButton addTarget:self action:@selector(pickerButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
        [_picker addSubview:pickerButton];
    }

    if (_pickerBackgroundColor) {
        [_picker setBackgroundColor:_pickerBackgroundColor];
    }

    if (_pickerBackgroundImage) {
        UIImageView *backgroundImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _picker.frame.size.width, _picker.frame.size.height)];
        [backgroundImage setImage:_pickerBackgroundImage];

        [_picker addSubview:backgroundImage];
    }

    if (_enablePickerChin) {
        UIView *chin;

        if (_pickerChinSize.height > 0 && _pickerChinSize.width > 0) {
            chin = [[UIView alloc] initWithFrame:CGRectMake(0, _picker.frame.size.height - _pickerChinSize.height, _pickerChinSize.width, _pickerChinSize.height)];
        } else{
            chin = [[UIView alloc] initWithFrame:CGRectMake(0, _picker.frame.size.height-2, _picker.frame.size.width/4, 2)];;
        }

        if (_pickerChinColor) {
            [chin setBackgroundColor:_pickerChinColor];
        } else{
            [chin setBackgroundColor:[UIColor blackColor]];
        }
        [chin setBackgroundColor:[UIColor redColor]];
        self.chin=chin;
        [self.view addSubview:self.chin];


    }

    [_picker setScrollEnabled:NO];
    startingPageScrollViewContentOffsetX =0;
   // startingPageScrollViewContentOffsetX = -((_picker.frame.size.width/2) - ((self.view.frame.size.width/3)/2));

    [_picker setContentOffset:CGPointMake(startingPageScrollViewContentOffsetX, 0)];

    [self.view addSubview:_picker];

    [[_picker.subviews firstObject] setSelected:YES];

    currentSelectedPickerButton = 0;
}

- (void)createPageViewController{
    _pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
    [_pageViewController setViewControllers:@[[_viewControllers firstObject] ] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
    [_pageViewController.view setFrame:CGRectMake(0, _picker.frame.size.height, self.view.frame.size.width, self.view.frame.size.height-_picker.frame.size.height)];
    _pageViewController.dataSource = self;
    _pageViewController.delegate = self;

    [(UIScrollView*)[_pageViewController.view.subviews firstObject] setDelegate:self];

    [self.view addSubview:_pageViewController.view];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)pickerButtonTapped:(UIButton*)sender{
    [_picker setContentOffset:CGPointMake(-((_picker.frame.size.width/2) - ((self.view.frame.size.width/3)/2)) + (((_picker.frame.size.width/2) - ((self.view.frame.size.width/3)/2)) * sender.tag), 0) animated:YES];

    [[_picker.subviews objectAtIndex:currentSelectedPickerButton] setSelected:NO];

    if (currentSelectedPickerButton < sender.tag) {
        [_pageViewController setViewControllers:@[[_viewControllers objectAtIndex:currentSelectedPickerButton+1]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
    } else if (currentSelectedPickerButton > sender.tag){
        [_pageViewController setViewControllers:@[[_viewControllers objectAtIndex:currentSelectedPickerButton-1]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
    }

    currentSelectedPickerButton = sender.tag;

    [sender setSelected:YES];
}

- (void)configurePickerButtonsWithNextButton:(int)buttonTag{
    [_picker setContentOffset:CGPointMake(-((_picker.frame.size.width/2) - ((self.view.frame.size.width/3)/2)) + (((_picker.frame.size.width/2) - ((self.view.frame.size.width/3)/2)) * buttonTag), 0) animated:YES];

    [[_picker.subviews objectAtIndex:currentSelectedPickerButton] setSelected:NO];

    currentSelectedPickerButton = buttonTag;

    [[_picker.subviews objectAtIndex:buttonTag] setSelected:YES];
}

#pragma mark -  UIPageViewControllerDatasource Methods
- (UIViewController*)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{
    NSUInteger index = [_viewControllers indexOfObject:viewController];

    if (index == 0) {
        return nil;
    } else{
        return (UIViewController*)[_viewControllers objectAtIndex:index-1];
    }
}

- (UIViewController*)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
    NSUInteger index = [_viewControllers indexOfObject:viewController];

    if (index == _viewControllers.count-1) {
        return nil;
    } else{
        return (UIViewController*)[_viewControllers objectAtIndex:index+1];
    }
}

#pragma mark - UIPageViewControllerDelegate Methods
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{
    if (completed) {
        [self pickerButtonTapped:(UIButton*)[_picker.subviews objectAtIndex:[_viewControllers indexOfObject:[[pageViewController viewControllers] firstObject]]]];
    }
    gestureDrivenTransition = NO;
}

- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers{
    gestureDrivenTransition = YES;
}

#pragma mark - UIScrollViewDelegate Methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidScroll | contentOffset.x:%f",scrollView.contentOffset.x );
    if (gestureDrivenTransition) {
        if (scrollView.contentOffset.x != self.view.frame.size.width) {
            float newWidth = startingPageScrollViewContentOffsetX + (((_picker.frame.size.width * currentSelectedPickerButton) + (scrollView.contentOffset.x - self.view.frame.size.width))/3);

            if ((scrollView.contentOffset.x - self.view.frame.size.width) == scrollView.frame.size.width/2) {
                //half way there


                //Not sure how to calculate this so that the chin moves smoothly and snaps into place depending on where the user has swipped to via the pager hosting the VC's
                [_chin setFrame:CGRectMake(_chin.frame.origin.x, _chin.frame.origin.y, _chin.frame.size.width,_chin.frame.size.height)];

            }

            //[_picker setContentOffset:CGPointMake(newWidth, 0)];
        }
    }
}

@end

【问题讨论】:

    标签: ios tabs uiscrollview uipageviewcontroller uipagecontrol


    【解决方案1】:

    我做了一个类似的项目,它可能会有所帮助:MXSegmentedPager

    【讨论】:

    • 如何以编程方式滚动视差标题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多