programing

UIPageViewController 내의 슬라이딩 페이지 위에 UIPageControl 요소를 배치하는 방법은 무엇입니까?

nasanasas 2020. 12. 7. 08:14
반응형

UIPageViewController 내의 슬라이딩 페이지 위에 UIPageControl 요소를 배치하는 방법은 무엇입니까?


UIPageViewController로 앱을 구현하는 방법에 대한 AppCoda 의이 튜토리얼 과 관련 하여 하단 대신 페이지 상단에 사용자 정의 페이지 제어 요소를 사용하고 싶습니다.

표시 될 단일보기 위에 페이지 제어 요소를 놓았을 때, 논리적 결과는 제어 요소가 화면에서 페이지보기와 함께 스크롤된다는 것입니다.

페이지 뷰가 전체 화면 (이미지 포함)이되도록 뷰 위에 컨트롤 요소를 배치하여 사용자가 고정 된 컨트롤 요소 아래의 뷰를 볼 수 있도록하는 방법은 무엇입니까?

예제 스크린 샷을 첨부했습니다. AppCoda 및 Path에 대한 크레딧 :

여기에 이미지 설명 입력


이 문제의 원인이 된 답변에 대해 언급 할 담당자는 없었지만 정말 마음에 듭니다. 코드를 개선하고 UIPageViewController의 아래 하위 클래스에 대해 신속하게 변환했습니다.

class UIPageViewControllerWithOverlayIndicator: UIPageViewController {
    override func viewDidLayoutSubviews() {
        for subView in self.view.subviews as! [UIView] {
            if subView is UIScrollView {
                subView.frame = self.view.bounds
            } else if subView is UIPageControl {
                self.view.bringSubviewToFront(subView)
            }
        }
        super.viewDidLayoutSubviews()
    }
}

깨끗하고 잘 작동합니다. 아무것도 유지할 필요가 없습니다. 페이지보기 컨트롤러를 스토리 보드에서이 클래스의 인스턴스로 만들거나 사용자 지정 페이지보기 컨트롤러 클래스가이 클래스를 대신 상속하도록 만드십시오.


추가 조사와 검색 후 나는 stackoverflow에서도 해결책을 찾았습니다 .

키는 맞춤 UIPageControl요소 에 보낼 다음 메시지입니다 .

[self.view bringSubviewToFront:self.pageControl];

AppCoda 튜토리얼은이 솔루션의 기초입니다 .

화살표가있는 뷰 컨트롤러 UIPageControl위에 요소를 추가합니다 RootViewController.

.NET Framework에서 관련 IBOutlet요소를 만듭니다 ViewController.m.

에서 viewDidLoad방법 당신은 그 모든 하위 뷰를 추가 한 후 호출하는 최후의 수단으로 다음 코드를 추가해야합니다.

[self.view bringSubviewToFront:self.pageControl];

현재 컨텐츠보기의 pageIndex를 기반으로 현재 페이지를 지정하려면 UIPageViewControllerDataSource메소드에 다음을 추가 할 수 있습니다 .

- (UIPageViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    // ...
    index--;
    [self.pageControl setCurrentPage:index];

    return [self viewControllerAtIndex:index];
}

- (UIPageViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    // ...
    index++;
    [self.pageControl setCurrentPage:index];

    // ...
    return [self viewControllerAtIndex:index];
}

sn3ek 귀하의 답변은 저에게 대부분의 방법을 제공했습니다. viewControllerCreation그래도 방법을 사용하여 현재 페이지를 설정하지 않았습니다 .

내가 만든 ViewController also의 위임을 UIPageViewController. 그런 다음 그 방법으로 PageControl's CurrentPage설정했습니다 . pageIndex유지 관리를 사용하여 ContentViewController원본 기사에서 언급했습니다.

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
  APPChildViewController *currentViewController = pageViewController.viewControllers[0];
  [self.pageControl setCurrentPage:currentViewController.pageIndex];
}

이것을 추가하는 것을 잊지 마십시오 viewDidLoad

self.pageViewController.delegate = self;

PropellerHead의 의견에 대한 후속 조치를 위해 인터페이스는 다음 ViewController과 같은 형식을 갖습니다.

@interface ViewController : UIViewController <UIPageViewControllerDataSource, UIPageViewControllerDelegate>

UIPageViewController를 서브 클래 싱하고 다음과 같이 viewDidLayoutSubviews를 재정의하면 동일한 효과를 얻을 수 있습니다.

-(void)viewDidLayoutSubviews {
    UIView* v = self.view;
    NSArray* subviews = v.subviews;
    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 등을 유지할 필요가 없습니다.


다음은 다른 답변을 살펴본 후 작성한 RxSwift / RxCocoa 답변입니다.

let pages = Variable<[UIViewController]>([])
let currentPageIndex = Variable<Int>(0)
let pendingPageIndex = Variable<(Int, Bool)>(0, false)

let db = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()
    pendingPageIndex
        .asDriver()
        .filter { $0.1 }
        .map { $0.0 }
        .drive(currentPageIndex)
        .addDisposableTo(db)

    currentPageIndex.asDriver()
        .drive(pageControl.rx.currentPage)
        .addDisposableTo(db)
}

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    if let index = pages.value.index(of: pendingViewControllers.first!) {
        pendingPageIndex.value = (index, false)
    }
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    pendingPageIndex.value = (pendingPageIndex.value.0, completed)
}

사용자 지정을 구현 UIPageControl하고보기에 추가해야합니다. 다른 사람들이 언급했듯이 view.bringSubviewToFront(pageControl)호출해야합니다.

사용자 정의 (스토리 보드에서) 설정에 대한 모든 코드가 포함 된 뷰 컨트롤러 예가 있습니다.UIPageControlUIPageViewController

현재 페이지 표시기를 설정하기 위해 구현해야하는 두 가지 방법이 있습니다.

func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
    pendingIndex = pages.indexOf(pendingViewControllers.first!)
}

func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if completed {
        currentIndex = pendingIndex
        if let index = currentIndex {
            pageControl.currentPage = index
        }
    }
}

위의 @zerotool의 답변을 기반으로 한 Swifty 2 답변이 있습니다. UIPageViewController를 하위 클래스로 만든 다음이 재정의를 추가하여 scrollview를 찾고 크기를 조정하십시오. 그런 다음 페이지 컨트롤을 잡고 다른 모든 항목의 맨 위로 이동합니다. 또한 페이지 컨트롤 배경색을 지우도록 설정해야합니다. 마지막 두 줄은 앱 델리게이트에 들어갈 수 있습니다.

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()

    var sv:UIScrollView?
    var pc:UIPageControl?

    for v in self.view.subviews{

        if v.isKindOfClass(UIScrollView) {

            sv = v as? UIScrollView

        }else if v.isKindOfClass(UIPageControl) {

            pc = v as? UIPageControl
        }
    }

    if let newSv = sv {

        newSv.frame = self.view.bounds
    }

    if let newPc = pc {

        self.view.bringSubviewToFront(newPc)
    }
}

let pageControlAppearance = UIPageControl.appearance()
pageControlAppearance.backgroundColor = UIColor.clearColor()

btw-위에서 언급했듯이 무한 루프를 발견하지 못했습니다.

참고 URL : https://stackoverflow.com/questions/21045630/how-to-put-the-uipagecontrol-element-on-top-of-the-sliding-pages-within-a-uipage

반응형