ios - PageViewController 和屏幕/数据刷新

标签 ios swift uipageviewcontroller

我正在学习如何使用 PageViewController,在我构建的应用程序中,我需要能够从包含的 ViewController 刷新屏幕上的内容。

所以在我的 Storyboard中我有:

一个 View Controller ,类 RoomPageListViewController

一个 View Controller ,类 RoomContentViewController,它有许多使用 CoreData 更新的标签。

一个 PageViewController

设置非常简单,如果需要我可以放入整个代码,但我想做的是从 RoomPageListViewController 调用 RoomContentViewController 中的函数更新标签并让用户留在他们所在的页面上。

无论我尝试什么都会导致错误,例如尝试:

 let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("RoomContentViewController") as! RoomContentViewController
 pageContentViewController.updateScreen()

但运气不好...我如何才能做到这一点,还是我以“错误”的方式做到了?

谢谢!

EDIT v3:协议(protocol)实现现在可以正常工作了!

这是 RoomPageListViewController 的代码:

class RoomPageListViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    var roomContentVCAccess: RoomContentVCAccess!

    var roomsList: Array<String> = ["Entire Home"]
    var roomButtonClicked: String = ""
    let activityInd: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
    var showInd: Bool = true
    let shadowLabel: UILabel = UILabel(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height))
    var viewBySelection: Int = 1
    var roomDeviceGroupID: Int = 0
    var redrawBool: Bool = true
    var displayRoom: String = ""

    var pageViewController : UIPageViewController!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.title = "Devices By Room"

        var backBtn : UIBarButtonItem = UIBarButtonItem(title: " ", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
        self.navigationItem.leftBarButtonItem = backBtn
        self.navigationItem.leftBarButtonItem?.enabled = false

        var settingsBtn : UIBarButtonItem = UIBarButtonItem(title: "Settings", style: UIBarButtonItemStyle.Plain, target: self, action: "goSettings")
        self.navigationItem.rightBarButtonItem = settingsBtn

        activityInd.stopAnimating()

        if showInd == true {
            startInd()
        }

    }


    func startInd() {
        shadowLabel.backgroundColor = UIColor.lightGrayColor()
        shadowLabel.text = "Please Wait... Loading Data...\n\n\n\n\n"
        shadowLabel.numberOfLines = 6
        shadowLabel.textAlignment = NSTextAlignment.Center

        let screenSize: CGRect = UIScreen.mainScreen().bounds
        shadowLabel.center = CGPoint (x: screenSize.width/2 , y: screenSize.height/2)
        shadowLabel.alpha = 0.5
        shadowLabel.hidden = false

        activityInd.center = CGPoint (x: screenSize.width/2 , y: screenSize.height/2)
        activityInd.color = UIColor.blueColor()
        activityInd.startAnimating()
        activityInd.hidden = false

        self.view.addSubview( shadowLabel )
        self.view.addSubview( activityInd )

    }

    func stopInd() {
        shadowLabel.hidden = true
        activityInd.stopAnimating()
        activityInd.hidden = true

        showRooms()

        if (redrawBool == true) {
            //showRooms()
            reset()
        } else {
            self.roomContentVCAccess.updateScreen()
        }


        redrawBool = false
    }

    func showRooms() {
        roomsList = ["Entire Home"]

        var serverSettings:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
        var managedContext: NSManagedObjectContext = serverSettings.managedObjectContext!
        var request = NSFetchRequest(entityName: "Devices")
        request.propertiesToFetch = NSArray(objects: "room") as [AnyObject]
        request.resultType = NSFetchRequestResultType.DictionaryResultType
        request.returnsDistinctResults = true
        let deviceFilter = NSPredicate (format: "room <> %@", "Unknown")
        request.predicate = deviceFilter

        var roomsResults: Array<AnyObject> = managedContext.executeFetchRequest(request, error: nil)!

        println("count: \(roomsResults.count)")

        if roomsResults.count > 0 {


            for room in roomsResults {

                var theroom = room["room"] as! String

                if (theroom != "Alarm") {
                    roomsList.append(theroom)
                }

            }

        }

        println(roomsList)
    }

    func reset() {
        /* Getting the page View controller */
        pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
        self.pageViewController.dataSource = self

        let pageContentViewController = self.viewControllerAtIndex(0)
        self.pageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)

        self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
        self.addChildViewController(pageViewController)
        self.view.addSubview(pageViewController.view)
        self.pageViewController.didMoveToParentViewController(self)

        //stopInd()
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        var index = (viewController as! RoomContentViewController).pageIndex!

        index++

        return self.viewControllerAtIndex(index)

    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        var index = (viewController as! RoomContentViewController).pageIndex!

        if (index <= 0) {
            return nil
        }

        index--

        return self.viewControllerAtIndex(index)

    }

    func viewControllerAtIndex(index : Int) -> UIViewController? {
        if ((self.roomsList.count == 0) || (index >= self.roomsList.count)) {
            return nil
        }

        let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("RoomContentViewController") as! RoomContentViewController

        self.roomContentVCAccess = pageContentViewController

        pageContentViewController.room = self.roomsList[index]
        pageContentViewController.pageIndex = index

        displayRoom = self.roomsList[index]

        return pageContentViewController
    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {

        return roomsList.count
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {

        return 0
    }




}

和 RoomContentViewController 的代码:

 protocol RoomContentVCAccess {
     func updateScreen()
}

class RoomContentViewController: UIViewController, RoomContentVCAccess {

    var pageIndex: Int?
    var room : String!

    @IBOutlet weak var screenScrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        screenScrollView.contentSize = CGSizeMake(screenScrollView.frame.size.width, 650)

        roomName.text = room

        btnViewAllRoomSensors.layer.cornerRadius = 10
        btnViewAllRoomSensors.layer.masksToBounds = true

        updateScreen()

    }

    override func viewDidAppear(animated: Bool) {
        updateScreen()
    }


    func updateScreen() {
        println(room)
        let roomValues = getLabelValues(room)
        println(roomValues)
        var roomDevicesCount: Array<Int> = roomValues[0] as! Array<Int>


        // more code here....

    }

    func getLabelValues(roomName: String) -> (Array<AnyObject>) {

        var serverSettings:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
        var managedContext: NSManagedObjectContext = serverSettings.managedObjectContext!
        var request = NSFetchRequest(entityName: "Devices")

        let deviceFilter = NSPredicate (format: "room = %@", roomName)

        // more CoreData code...

    }

总体情况是应用程序一旦收到数据就会调用 RoomPageListViewController 中的 stopInd()。在 stopInd() 中,我需要能够调用 RoomContentViewController 中的 updateScreen()。

最佳答案

您可以创建一个协议(protocol),让拥有标签的 ViewController 遵守该协议(protocol)。例如:

protocol RoomContentVCAccess
{
    func updateLabels()
}

然后在你的 RoomContentViewController 的类声明中:

class RoomContentViewController: UIViewController, RoomContentVCAccess
{
    // ...

    // MARK: - RoomContentVCAccess
    func updateLabels()
    {
        // update your labels
    }
}

您的 RoomPageListViewController 还必须知道他的 roomContentVCAccess 是谁。为此,只需在 RoomPageListViewController 中创建一个实例变量:var roomContentVCAccess: RoomContentVCAccess! 然后说 self.roomContentVCAccess = viewController as! viewControllerAtIndex 函数中的 RoomContentViewController

然后当在 RoomPageListViewController 中调用 stopInd() 时,说 self.roomContentVCAccess.updateLabels()

关于ios - PageViewController 和屏幕/数据刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31701374/

相关文章:

iphone - 加速 UIPageViewController

ios - 链接到 Swift 包中的胖静态库

ios - 在 ios 中缓存视频

iphone - 如何在运行时从 UITableView 添加或删除行?

swift - 从 Firebase 获取信息 : Swift

ios - UIPageViewController 在进入主页时堆叠 ViewController

ios - 将 JSON 转换为自定义对象时出错

swift - mac app打开后如何执行命令

ios - UIPageViewController 是否必须全屏?

ios - UIPageViewController 断言失败