ios 如何使用 UIPageViewController 半透明的点制作底部栏?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17779735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make the bottom bar with dots of a UIPageViewController translucent?
提问by Mike V
I'm in the process of making a tutorial, and I'm trying to emulate the style of Path's tutorial like so:
我正在制作教程,我正在尝试像这样模仿 Path 教程的风格:
http://www.appcoda.com/wp-content/uploads/2013/06/UIPageViewController-Tutorial-Screen.jpg
http://www.appcoda.com/wp-content/uploads/2013/06/UIPageViewController-Tutorial-Screen.jpg
My issue is that if set the delegate method as so:
我的问题是,如果将委托方法设置为:
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
return 5;
}
Then I get this stupid black bar under the dots:
然后我在点下看到了这个愚蠢的黑条:
http://i.stack.imgur.com/pUEdh.png
http://i.stack.imgur.com/pUEdh.png
Is there a way to make this bar translucent in a way thats similar to setting a UINavigationBar to translucent?
有没有办法以类似于将 UINavigationBar 设置为半透明的方式使该栏半透明?
回答by Alex R. R.
It is very easy to make it work. You just only have to make the pageviewcontroller taller, and place a PageControl into the XIB file. The trick is put the PageControl in the foreground (and all the other common controls) at the beginning, and update the content of the PageControl with the PageViewController. Here is the code:
让它工作非常容易。您只需要使 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;
}
回答by zeroimpl
The same effect can be achieved simply by subclassing UIPageViewController and overriding viewDidLayoutSubviews as follows:
同样的效果可以简单地通过继承 UIPageViewController 并覆盖 viewDidLayoutSubviews 来实现,如下所示:
-(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];
}
Then there is no need to maintain a separate UIPageControl and such.
那么就没有必要维护一个单独的 UIPageControl 之类的了。
回答by Oleksandr Buravlyov
Swift 3 snippet
Swift 3 片段
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let scrollView = view.subviews.filter({ 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()
}
is UIScrollView }).first,
let pageControl = view.subviews.filter({ - (UIPageControl *)getPageControlForPageViewController:(UIPageViewController *)pageViewController {
for (UIView *subview in self.pageViewController.view.subviews) {
if ([subview isKindOfClass:[UIPageControl class]]) {
return (UIPageControl *) subview;
}
}
return nil;
}
is UIPageControl }).first {
scrollView.frame = view.bounds
view.bringSubview(toFront:pageControl)
}
}
回答by markedwardmurray
Here's a conversion of Zerotool's solution into Swift 2.1, though there's probably a more elegant way to write it:
这是 Zerotool 的解决方案到 Swift 2.1 的转换,尽管可能有更优雅的编写方式:
self.childPageControl = [self getPageControlForPageViewController:self.pageViewController];
回答by Caleb
I don't think you can change the behavior of UIPageViewController, so it seems likely that the Path app uses its own view controller. You can do the same: create your own container view controller that uses a UIPageControl to indicate the current page.
我认为您无法更改 UIPageViewController 的行为,因此 Path 应用程序似乎使用自己的视图控制器。你也可以这样做:创建你自己的容器视图控制器,它使用 UIPageControl 来指示当前页面。
回答by Carter Hudson
You can simply adjust the alpha of the UIPageViewController's UIPageControl.
您可以简单地调整 UIPageViewController 的 UIPageControl 的 alpha。
First, you should retrieve it from the UIPageViewController like so:
首先,您应该像这样从 UIPageViewController 检索它:
self.childPageControl.alpha = .5;
Next, make use of the function. I've made a property on my ViewController called childPageControl. Give it the UIPageViewController's UIPageControl:
接下来,使用该功能。我在我的 ViewController 上创建了一个名为 childPageControl 的属性。给它 UIPageViewController 的 UIPageControl:
self.pageController.dataSource = self;
CGRect rect = [self.view bounds];
rect.size.height+=37;
[[self.pageController view] setFrame:rect];
NSArray *subviews = self.pageController.view.subviews;
UIPageControl *thisControl = nil;
for (int i=0; i<[subviews count]; i++) {
if ([[subviews objectAtIndex:i] isKindOfClass:[UIPageControl class]]) {
thisControl = (UIPageControl *)[subviews objectAtIndex:i];
}
}
UIView *tempview = [[UIView alloc] initWithFrame:CGRectMake(0, -30, 320, 40)];
[tempview addSubview:thisControl];
thisControl.pageIndicatorTintColor = [UIColor lightGrayColor];
thisControl.currentPageIndicatorTintColor = [UIColor greenColor];
[self.view addSubview:tempview];
Next, you can adjust the alpha to give a translucent effect:
接下来,您可以调整 alpha 以提供半透明效果:
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()
}
}
}
You're very limited in what you can do to affect the UIPageViewController's UIPageControl, but you can at least achieve this with little effort.
您在影响 UIPageViewController 的 UIPageControl 方面所能做的非常有限,但您至少可以毫不费力地实现这一目标。
回答by mandeep-dhiman
Small hack I found today..
我今天发现的小黑客..
Please see the code below.
请看下面的代码。
- (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];
}
回答by Mohsin Qureshi
this code is in Swift Add following in your UIPageViewController
这段代码在 Swift 中在你的 UIPageViewController 中添加以下内容
- (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];
}
}
回答by MMSousa
I solve using this code:
我使用此代码解决:
##代码##回答by crafterm
I wanted to do a similar effect in the app I was working on - I used a UIPageViewController with a separate UIPageControl.
我想在我正在开发的应用程序中实现类似的效果 - 我使用了一个带有单独 UIPageControl 的 UIPageViewController。
This lets you place the UIPageControl anywhere you'd like in the view, including over the top of the UIPageViewController, and you keep its active page dot up to date via the UIPageViewController delegate method:
这使您可以将 UIPageControl 放置在视图中您想要的任何位置,包括 UIPageViewController 的顶部,并且您可以通过 UIPageViewController 委托方法使其活动页面点保持最新:
##代码##No need to traverse the subview hierarchy trying to find the internal UIPageViewController page control, nor having to resize the contents of the internal scrollview.
无需遍历子视图层次结构试图找到内部 UIPageViewController 页面控件,也不必调整内部滚动视图的内容大小。
Hope this helps.
希望这可以帮助。