RoomPageListViewController

RoomPageListViewController

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

所以在我的情节提要中,我有:

一个视图控制器,类RoomPageListViewController

一个视图控制器,类RoomContentViewController,它具有许多使用CoreData更新的标签。

一个PageViewController

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

我尝试过的一切都会导致错误,例如尝试过:

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

但是没有运气...我怎么能做到这一点?还是我以“错误”的方式做到了?

谢谢!

编辑v3:协议实现现在可以正常工作!

这是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()。

最佳答案

您可以创建拥有标签的ViewController遵守的协议。例如:

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! RoomContentViewController -function中说出viewControllerAtIndex

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

10-08 12:26