Iphone 如何使带有UIPageViewController点的底部栏半透明?
我正在制作一个教程,我试图模仿Path教程的风格,如下所示: 我的问题是,如果将委托方法设置为:Iphone 如何使带有UIPageViewController点的底部栏半透明?,iphone,ios,uipageviewcontroller,Iphone,Ios,Uipageviewcontroller,我正在制作一个教程,我试图模仿Path教程的风格,如下所示: 我的问题是,如果将委托方法设置为: - (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController { // The number of items reflected in the page indicator. return 5; } 然后我在圆点下面画了一条愚蠢的黑条: 是否有一
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
return 5;
}
然后我在圆点下面画了一条愚蠢的黑条:
是否有一种方法可以使此栏半透明,其方式类似于将UINavigationBar设置为半透明?我认为您无法更改UIPageViewController的行为,因此路径应用程序可能使用自己的视图控制器。您也可以这样做:创建自己的容器视图控制器,该控制器使用UIPageControl来指示当前页面。使其工作起来非常容易。只需将pageviewcontroller设置得更高,并将PageControl放置到XIB文件中即可。 诀窍是在开始时将PageControl(以及所有其他常用控件)放在前台,并使用PageViewController更新PageControl的内容。代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageController.dataSource = self;
// We need to cover all the control by making the frame taller (+ 37)
[[self.pageController view] setFrame:CGRectMake(0, 0, [[self view] bounds].size.width, [[self view] bounds].size.height + 37)];
TutorialPageViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
// Bring the common controls to the foreground (they were hidden since the frame is taller)
[self.view bringSubviewToFront:self.pcDots];
[self.view bringSubviewToFront:self.btnSkip];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [(TutorialPageViewController *)viewController index];
[self.pcDots setCurrentPage:index];
if (index == 0) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [(TutorialPageViewController *)viewController index];
[self.pcDots setCurrentPage:index];
index++;
if (index == 3) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (TutorialPageViewController *)viewControllerAtIndex:(NSUInteger)index {
TutorialPageViewController *childViewController = [[TutorialPageViewController alloc] initWithNibName:@"TutorialPageViewController" bundle:nil];
childViewController.index = index;
return childViewController;
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
NSInteger tutorialSteps = 3;
[self.pcDots setNumberOfPages:tutorialSteps];
return tutorialSteps;
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return 0;
}
您可以简单地调整UIPageViewController的UIPageControl的alpha 首先,您应该从UIPageViewController中检索它,如下所示:
- (UIPageControl *)getPageControlForPageViewController:(UIPageViewController *)pageViewController {
for (UIView *subview in self.pageViewController.view.subviews) {
if ([subview isKindOfClass:[UIPageControl class]]) {
return (UIPageControl *) subview;
}
}
return nil;
}
接下来,使用该函数。我在ViewController上创建了一个名为childPageControl的属性。将UIPageViewController的UIPageControl指定给它:
self.childPageControl = [self getPageControlForPageViewController:self.pageViewController];
接下来,可以调整alpha以提供半透明效果:
self.childPageControl.alpha = .5;
要影响UIPageViewController的UIPageControl,您所能做的非常有限,但您至少可以轻松实现这一点。只需将UIPageViewController子类化并覆盖ViewDidLayoutSubview,即可实现相同的效果,如下所示:
-(void)viewDidLayoutSubviews {
UIView* v = self.view;
NSArray* subviews = v.subviews;
// Confirm that the view has the exact expected structure.
// If you add any custom subviews, you will want to remove this check.
if( [subviews count] == 2 ) {
UIScrollView* sv = nil;
UIPageControl* pc = nil;
for( UIView* t in subviews ) {
if( [t isKindOfClass:[UIScrollView class]] ) {
sv = (UIScrollView*)t;
} else if( [t isKindOfClass:[UIPageControl class]] ) {
pc = (UIPageControl*)t;
}
}
if( sv != nil && pc != nil ) {
// expand scroll view to fit entire view
sv.frame = v.bounds;
// put page control in front
[v bringSubviewToFront:pc];
}
}
[super viewDidLayoutSubviews];
}
这样就不需要维护单独的UIPageControl等。我找到了另一个更适合我的工作区 我重用以获取UIPageControl(称为pageControl的变量)和UIPageViewController使用的UIScrollView(称为pageView的变量) 一旦在viewDidLoad中完成了这项操作,我就阻止了pageView的clip子视图,并让内容传播到UIPageControl之下 pageControl位于pageView下方,因此我们必须手动将其置于前面
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
if(
[[[self view] subviews] count] == 2
)
{
UIScrollView* pageView = nil;
UIPageControl* pageControl = nil;
UIView* selfView = self.view;
NSArray* subviews = selfView.subviews;
for( NSInteger i = 0 ; i < subviews.count && ( pageView == nil || pageControl == nil ) ; i++ )
{
UIView* t = subviews[i];
if( [t isKindOfClass:[UIScrollView class]] )
{
pageView = (UIScrollView*)t;
}
else if( [t isKindOfClass:[UIPageControl class]] )
{
pageControl = (UIPageControl*)t;
}
}
if( pageView != nil && pageControl != nil )
{
[pageView setClipsToBounds:NO];
[selfView bringSubviewToFront:pageControl];
}
}
}
-(void)viewDidLoad
{
[超级视图下载];
//加载视图后执行任何其他设置。
如果(
[[[self view]子视图]计数]==2
)
{
UIScrollView*pageView=nil;
UIPageControl*pageControl=nil;
UIView*selfView=self.view;
NSArray*子视图=selfView.subview;
对于(NSInteger i=0;i
一旦我的pageView覆盖了pageControl占用的空间,但在pageControl下,我只需调整显示为page的每个viewController的nib文件使用:
- 基础视图不应剪裁
- 第一个也是唯一的子视图:
- 应具有从superview底部将底部设置为-37的约束(如果需要,可以设置为更多,但37是页面控件的大小)
- 应该剪辑内容吗
- (void)pageViewController:(UIPageViewController *)pageViewController
didFinishAnimating:(BOOL)finished
previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers
transitionCompleted:(BOOL)completed {
if (completed) {
self.pageControl.currentPage = [self.pageViewControllers indexOfObject:pageViewController.viewControllers.firstObject];
}
}
-(无效)pageViewController:(UIPageViewController*)pageViewController
完成了
PreviousViewController:(NSArray*)PreviousViewController
过渡已完成:(BOOL)已完成{
如果(已完成){
self.pageControl.currentPage=[self.pageViewController索引对象:pageViewController.ViewController.firstObject];
}
}
无需遍历子视图层次结构来查找内部UIPageViewController页面控件,也无需调整内部scrollview内容的大小
希望这能有所帮助。我今天发现的小黑客 请参阅下面的代码
self.pageController.dataSource=self;
CGRect rect=[self.view bounds];
矩形尺寸高度+=37;
[[self.pageController view]setFrame:rect];
NSArray*子视图=self.pageController.view.subview;
UIPageControl*thisControl=nil;
对于(int i=0;i这里是Zerotool的解决方案到Swift 2.1的转换,尽管可能有一种更优雅的方式来编写它:
override func viewDidLayoutSubviews() {
var scrollView: UIScrollView?
var pageControl: UIPageControl?
// If you add any custom subviews, you will want to remove this check.
if (self.view.subviews.count == 2) {
for view in self.view.subviews {
if (view.isKindOfClass(UIScrollView)) {
scrollView = view as? UIScrollView
} else if (view.isKindOfClass(UIPageControl)) {
pageControl = view as? UIPageControl
}
}
}
if let scrollView = scrollView {
if let pageControl = pageControl {
scrollView.frame = self.view.bounds
self.view.bringSubviewToFront(pageControl)
}
}
super.viewDidLayoutSubviews()
}
这个代码是用Swift写的
在UIPageViewController中添加以下内容
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews {
if view.isKindOfClass(UIScrollView) {
view.frame = UIScreen.mainScreen().bounds
} else if view.isKindOfClass(UIPageControl) {
view.backgroundColor = UIColor.clearColor()
}
}
}
Swift 3片段
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let scrollView = view.subviews.filter({ $0 is UIScrollView }).first,
let pageControl = view.subviews.filter({ $0 is UIPageControl }).first {
scrollView.frame = view.bounds
view.bringSubview(toFront:pageControl)
}
}
我使用以下代码进行求解:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.namesImage = @[@"page1.png", @"page2.png", @"page3.png", @"page4.png"];
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
self.pageViewController.dataSource = self;
TutorialContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = @[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
[[UIPageControl appearance] setPageIndicatorTintColor:[UIColor grayColor]];
[[UIPageControl appearance] setCurrentPageIndicatorTintColor:[UIColor whiteColor]];
[[UIPageControl appearance] setBackgroundColor: [[UIColor blackColor] colorWithAlphaComponent:0.1f]];
[[UIPageControl appearance] setOpaque:YES];
}
Swift 5.2
您可以根据需要使用此代码
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let myScrollView = view.subviews.filter({ $0 is UIScrollView }).first,
let myPageControl = view.subviews.filter({ $0 is UIPageControl }).first {
myScrollView.frame = view.bounds
view.bringSubviewToFront(myPageControl)
}
}
@MikeV如果你想要框架缺少的功能,向苹果提交一份bug报告是没有坏处的。很好,我可能会这么做。与此同时,我似乎在重写代码来解释这一点。我很惊讶。我在我的基本实用程序应用程序上使用了UiPageControl,默认情况下它是透明的。@Robvandervier问题并不是真正的问题控件的重要性,是由UIPageViewController管理的视图的大小以及UIPageControl在黑色背景上的位置。这不太好。只需转到第一页或最后一页,向无法转到的方向滚动,然后看着索引被抛出。@AdamPro13我同意,这对我也不起作用。我通过实现UIPageViewController使其正常工作
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let myScrollView = view.subviews.filter({ $0 is UIScrollView }).first,
let myPageControl = view.subviews.filter({ $0 is UIPageControl }).first {
myScrollView.frame = view.bounds
view.bringSubviewToFront(myPageControl)
}
}