Откройте UISplitViewController для просмотра мастера, а не детали
У меня есть интерфейс с разделенным изображением с целевым приложением iPhone 6. При первом запуске приложения открывается подробный вид; Я бы хотел, чтобы он открылся для Мастера. Я пробовал:
self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.PrimaryOverlay
Что было предложено в другом месте qaru.site/info/551707/..., но, похоже, он ничего не делает и не открывает мастер-представление при запуске. Я также попытался добавить следующую строку в свой AppDelegate:
splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
Но, несмотря на возвращение true или false (Другой вопрос о переполнении стека), я не имел успеха.
Я запускал пример приложения Master-Detail в Xcode и загружался в представление Master на основе splitViewController: call return false; однако я не уверен, как сделать эту работу более сложной.
Ответы
Ответ 1
Swift
UISplitViewController отображает главный вид выше детализации в книжной ориентации - это не отображение основного вида, а представление подробного представления во всю ширину под основным видом.
UISplitViewController в портретной ориентации на iPhone показывает детализацию VC вместо основной о принципе механизма свертывания.
Этот настоящий адрес адресов:
- Мастер → Деталь (Компактная ширина)
- iPhone 4s, 5, 5s, SE, 6, 6s, 7 (любая ориентация)
- iPod Touch
- любой айфон плюс (портрет)
- бок о бок (все другие размеры)
- IPad
- любой iPhone Plus (альбомная)
Вы должны установить preferredDisplayMode
. Вы бы хотели .primaryVisible
, если бы он существовал! Используя .allVisible
, iOS выбирает Detail
, если подходит только 1 вид (Компактная ширина); в этом размере код ниже выберет Master
.
Хитрость заключается в том, чтобы изменить preferredDisplayMode
на .allVisible
и вернуть true
в collapseSecondary:onto
.
class PrimarySplitViewController: UISplitViewController,
UISplitViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.preferredDisplayMode = .allVisible
}
func splitViewController(
_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController: UIViewController,
onto primaryViewController: UIViewController) -> Bool {
// Return true to prevent UIKit from applying its default behavior
return true
}
}
Ответ 2
Шаг 1 - Открыть MasterViewController
Шаг 2 - убедитесь, что в представлении таблицы есть протокол UISplitViewControllerDelegate. Например:
class ListVC: UITableViewController,UISplitViewControllerDelegate {}
Шаг 3 - добавьте его в ViewDidLoad
splitViewController?.delegate = self
Шаг 4. Затем переопределите этот метод, чтобы сказать, что контроллер главного представления должен всегда сворачиваться на контроллер подробного представления:
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
return true
}
Ответ 3
При первом запуске приложения открывается подробный вид; Я бы хотел, чтобы он открылся для просмотра мастера
Предполагая, что вы хотите это только при первом запуске, но не всегда; например, в том случае, если мастер-представление показывает пустой набор данных; то решение будет таким же, как и в шаблоне Master-Detail:
func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController:UIViewController, ontoPrimaryViewController primaryViewController:UIViewController) -> Bool {
guard let secondaryAsNavController = secondaryViewController as? UINavigationController else { return false }
guard let topAsDetailController = secondaryAsNavController.topViewController as? DetailViewController else { return false }
if topAsDetailController.detailItem == nil {
// Return true to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
return true
}
return false
}
Ответ 4
Это старый вопрос, и ни один из ответов не был для Задачи C, и даже когда я портировал ответы Swift, ни один из них не работал для меня. Один был близко, @SwiftArchitect.
Но он порекомендовал установить режим содержимого в .allVisible
(UISplitViewControllerDisplayModeAllVisible
в Objective C) - это заставляет главное представление постоянно отображаться, разделяя представление на главное с одной стороны, детали с другой. Это круто, но ОП попросил специально отобразить главное представление при первом запуске, что мне и нужно было сделать.
Изменением было использование UISplitViewControllerDisplayModePrimaryOverlay
для режима отображения.
Этот ответ для Xcode 9.4.1, цель развертывания 11.4.
Вот MasterViewController.h - вам нужно добавить UISplitViewControllerDelegate в объявлении протоколов:
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "MasterDetailDemo+CoreDataModel.h"
@class DetailViewController;
@interface MasterViewController : UITableViewController
<UISplitViewControllerDelegate,
NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) DetailViewController *detailViewController;
@property (strong, nonatomic) NSFetchedResultsController<Event *> *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@end
И затем в вашем MasterViewController.m вам нужно установить делегат контроллера разделенного представления и режим содержимого в ViewDidLoad, а затем вместе с ответом @SwiftArchitect также добавить метод делегата контроллера разделенного представления:
- (void)viewDidLoad {
[super viewDidLoad];
// needed to "slide out" MasterView on startup on iPad
self.splitViewController.delegate = self;
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
}
// split view delegate method
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
return true;
}
ПРИМЕЧАНИЕ. После некоторого тестирования я обнаружил, что метод делегирования с разделенным представлением и протокол с разделенным представлением не были необходимы. Без этого, похоже, работает точно так же. Возможно, это результат изменений в iOS, так как вопрос был первоначально задан и получен ответ.
Я получил это работает нормально, просто поместив эту строку в мой метод ViewDidLoad:
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
Ответ 5
Или просто унаследуйте от UISplitViewController
и используйте этот новый класс в раскадровке (на основе ответа SwiftArchitect):
class MasterShowingSplitViewController :UISplitViewController, UISplitViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.preferredDisplayMode = .allVisible
}
func splitViewController(
_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController: UIViewController,
onto primaryViewController: UIViewController) -> Bool {
// Return true to prevent UIKit from applying its default behavior
return true
}
}