PageViewController-白色背景

时间:2020-05-10 20:07:54

标签: uiview uiviewcontroller swiftui

我正在尝试将.background修饰符应用于由PageViewController表示的卡片。

红色背景未应用于我的卡,因为该卡似乎具有默认的白色背景。

He're my file and preview

import SwiftUI

struct PageView<Page:View>: View {

    var viewControllers: [UIHostingController<Page>]

    init(_ views: [Page]) {
        self.viewControllers = views.map { UIHostingController(rootView: $0)}
    }

    var body: some View {


        ZStack {

            Color.black
                .edgesIgnoringSafeArea(.all)

            PageViewController(controllers: viewControllers)
                .background(Color.red)

        }


    }

}

struct PageView_Previews: PreviewProvider {
    static var previews: some View {
        PageView(cards.map { OnboardingCardView(card: $0) })
    }
}

每张卡都来自CardView,并且此处没有背景应用于我的卡。

这是我的pageViewController代码:

    import SwiftUI

struct PageViewController: UIViewControllerRepresentable {

    var controllers: [UIViewController]

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UIPageViewController {

        let pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)

        pageViewController.dataSource = context.coordinator

        return pageViewController
    }

    func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {

        pageViewController.setViewControllers([controllers[0]], direction: .forward, animated: true)
    }

    class Coordinator: NSObject, UIPageViewControllerDataSource {
        var parent: PageViewController

        init(_ pageViewController: PageViewController) {
            self.parent = pageViewController
        }

        func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

            guard let index = parent.controllers.firstIndex(of: viewController) else {
                return nil
            }

            if index == 0 {
                return parent.controllers.last
            }

            return parent.controllers[index-1]

        }

        func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

            guard let index = parent.controllers.firstIndex(of: viewController) else {
                return nil
            }

            if index + 1 == parent.controllers.count {
                return parent.controllers.first
            }

            return parent.controllers[index+1]

        }

    }

}

这是什么问题? 非常感谢。

2 个答案:

答案 0 :(得分:1)

默认情况下,在UIHostingController中为每个确切的卡片设置背景。您可以将背景颜色手动设置为.clear,以使SwiftUI背景生效:

#include <iostream>

using namespace std;

int main()
{
    int data[3] = {1, 2, 3};
    if (data[2] == 2[data])
    {
        cout << "equal" << endl;
        cout << data[2] << ", " << 2[data] << endl;
    }
    else
    {
        cout << "not equal" << endl;
    }
}

答案 1 :(得分:0)

检查我对SwiftUI的完整UIPageViewController实现。它不使用UIKit,因此更易于控制。

import SwiftUI
extension OnboardingCard{
    static var test: [OnboardingCard]{
        [
        OnboardingCard(image: "onboarding", title: "Card 1", description: "Card 1 description."),
        OnboardingCard(image: "onboarding", title: "Card 2", description: "Card 2 description."),
        OnboardingCard(image: "onboarding", title: "Card 3", description: "Card 4 description.")
        ]
    }
}

struct ContentView: View {
    var directionForward = true
    @State var currentCard: OnboardingCard
    var cards: [OnboardingCard]
    @State var xOffset: CGFloat = 0
    init(cards newCards: [OnboardingCard]){
        self.cards = newCards
        guard let startCard = newCards.first else {fatalError("no cards")}
        self._currentCard = State(initialValue: startCard)
    }
    var body: some View {
        GeometryReader{geometry in
            HStack{
                ForEach(self.cardsSorted()){card in
                    OnboardingCardView(card: card)
                        .frame(width: geometry.size.width)
                }
            }
            .offset(x: self.xOffset, y: 0)
            .gesture(DragGesture()
            .onChanged(){value in
                self.xOffset = value.location.x - value.startLocation.x
                }
            .onEnded(){value in
                let inPercent = 100 * self.xOffset / (geometry.size.width / 2)
                let changedCount = inPercent / 100
                if changedCount < -1{//drag left to go to next one
                    guard let currentCardInd = self.cards.firstIndex(where: {$0.id == self.currentCard.id}) else{fatalError("cant find current card")}
                    let nextInd = self.cards.index(currentCardInd, offsetBy: Int(-changedCount))
                    if self.cards.indices.contains(nextInd){
                        self.currentCard = self.cards[nextInd]
                        self.xOffset = geometry.size.width + self.xOffset
                    }else{
                        guard let firstCard = self.cards.first else{fatalError("cant get first card")}
                        self.currentCard = firstCard
                        self.xOffset = geometry.size.width + self.xOffset
                    }
                }else if changedCount > 1{//drag right to go to previos one
                    guard let currentCardInd = self.cards.firstIndex(where: {$0.id == self.currentCard.id}) else{fatalError("cant find current card")}
                    let previosInd = self.cards.index(currentCardInd, offsetBy: Int(-changedCount))
                    if self.cards.indices.contains(previosInd){
                        self.currentCard = self.cards[previosInd]
                        self.xOffset = -geometry.size.width + self.xOffset
                    }else{
                        guard let lastCard = self.cards.last else{fatalError("cant get last card")}
                        self.currentCard = lastCard
                        self.xOffset = -geometry.size.width + self.xOffset
                    }
                }

                withAnimation(.easeInOut(duration: 0.5)){
                    self.xOffset = 0
                }
            })
        }
    }
    func cardsSorted() -> [OnboardingCard]{
        guard let currentCardInd = self.cards.firstIndex(where: {$0.id == self.currentCard.id}) else{fatalError("cant find current card")}
        guard let firstInd = self.cards.firstIndex(where: {$0.id == cards.first?.id}) else{fatalError("cant find current card")}
        guard let lastInd = self.cards.firstIndex(where: {$0.id == cards.last?.id}) else{fatalError("cant find current card")}
        var nextInd = self.cards.index(after: currentCardInd)
        if self.cards.indices.contains(nextInd) == false{
            nextInd = firstInd
        }
        var previosInd = self.cards.index(before: currentCardInd)
        if self.cards.indices.contains(previosInd) == false{
            previosInd = lastInd
        }
        return [self.cards[previosInd], self.cards[currentCardInd],self.cards[nextInd]]
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(cards: OnboardingCard.test)
    }
}

它的代码更少,并且逻辑透明。您可以根据需要修改检查以调整开关灵敏度(通过编辑比较if changedCount > 1)。您可以使用手势终点预测来计算和调整动画速度,甚至一次切换多个卡。这完全取决于您。或者,您可以按原样使用。