我正在学习如何使用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()
。