Я сделал простое приложение для погоды в качестве побочного проекта (я не программист), который показывает температуры в градусах Фаренгейта и Цельсия одновременно. Пользователь может проводить пальцем по горизонтали между городами:
![Franz Fahrenheit demo gif](https://i.stack.imgur.com/4l9VX.gif)
Я добился этого, используя шаблон многостраничного приложения, который был доступен в Xcode как новый шаблон приложения вплоть до Xcode 9. При создании приложения вплоть до Xcode 10 проблема заключалась в том, что когда пользователь добавлял город в массив городов, страницы для вновь добавленных городов не отображали , если пользователь был на последней странице карусели во время добавления нового города. Даже если это так, когда пользователь проведет пальцем влево, а затем назад вправо, появятся вновь добавленные города. Теперь, в Xcode 11, новые контроллеры представления для вновь добавленных городов никогда не рендерится, если пользователь не перезапустит приложение. Это довольно большая проблема, которую я хотел бы исправить.
Мне нужна помощь в выяснении того, как новые контроллеры представления могут отображаться по требованию в существующей многостраничной карусели после вызова addCity
, даже если пользователь в данный момент находится на последней странице и не требует перезапуска приложения.
Ниже приведен полный код, управляющий этой многостраничной каруселью. Извиняюсь за некоторые взломанные вещи там. Для контекста, я нетехнический менеджер по продукту, пытающийся сделать несколько приложений iOS побочными.
import UIKit
import StoreKit
/*
A controller object that manages a simple model
The controller serves as the data source for the page view controller; it therefore implements pageViewController:viewControllerBeforeViewController: and pageViewController:viewControllerAfterViewController:.
It also implements a custom method, viewControllerAtIndex: which is useful in the implementation of the data source methods, and in the initial configuration of the application.
There is no need to actually create view controllers for each page in advance -- indeed doing so incurs unnecessary overhead. Given the data model, these methods create, configure, and return a new view controller on demand.
*/
class ModelController: NSObject, UIPageViewControllerDataSource {
var rootViewController = RootViewController()
var cities = [""]
let defaults = UserDefaults.standard
let currentCount = UserDefaults.standard.integer(forKey: "launchCount")
var pageViewController: UIPageViewController?
override init() {
super.init()
self.cities = self.defaults.stringArray(forKey: "SavedStringArray") ?? [String]()
if self.cities == [""] || self.cities.count == 0 {
self.cities = ["Current Location", "San Francisco", "New York"]
}
}
func addCity(name:String) {
self.cities.append(name)
self.defaults.set(self.cities, forKey: "SavedStringArray")
}
func viewControllerAtIndex(_ index: Int, storyboard: UIStoryboard) -> DataViewController? {
// Return the data view controller for the given index.
if (self.cities.count == 0) || (index >= self.cities.count) {
return nil
}
// Create a new view controller and pass suitable data.
let dataViewController = storyboard.instantiateViewController(withIdentifier: "DataViewController") as! DataViewController
//get city name
dataViewController.dataObject = self.cities[index]
return dataViewController
}
func indexOfViewController(_ viewController: DataViewController) -> Int {
// Return the index of the given data view controller.
// For simplicity, this implementation uses a static array of model objects and the view controller stores the model object; you can therefore use the model object to identify the index.
return self.cities.firstIndex(of: viewController.dataObject) ?? NSNotFound
}
// MARK: - Page View Controller Data Source
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
var index = self.indexOfViewController(viewController as! DataViewController)
if (index == 0) || (index == NSNotFound) {
return nil
}
index -= 1
return self.viewControllerAtIndex(index, storyboard: viewController.storyboard!)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
var index = self.indexOfViewController(viewController as! DataViewController)
if index == NSNotFound {
return nil
}
index += 1
if index == self.cities.count {
return nil
}
if index > 1 && currentCount > 2 {
print ("request review")
SKStoreReviewController.requestReview()
}
return self.viewControllerAtIndex(index, storyboard: viewController.storyboard!)
}
}