问题描述
我的 Apple TV 应用列出了一系列 PDF,单击其中一个可将其绘制在屏幕上。但是,出于某种原因,当有人点击 Apple TV Remote 上的 / Menu 按钮时,它会完全退出应用程序。是什么导致它这样做?
首先是提取所有 PDF 列表的代码,然后是显示 PDF 的代码。
-(void)viewDidLoad {
[super viewDidLoad];
self.definesPresentationContext = YES; // kNow where you want UISearchController to be displayed
}
- (void)viewWillAppear:(BOOL)animated {
if (self.searchControllerWasActive) {
self.searchController.active = self.searchControllerWasActive;
_searchControllerWasActive = NO;
if (self.searchControllerSearchFieldWasFirstResponder) {
[self.searchController.searchBar becomeFirstResponder];
_searchControllerSearchFieldWasFirstResponder = NO;
}
}
NSBundle *bundle = [NSBundle mainBundle];
self.files = [bundle pathsForResourcesOfType:@"pdf" inDirectory:@"aimPDF"];
Nsstring *documentsDirectoryPath = [self.files objectAtIndex:thepath.row];
self.title = @"Devo Songs";
self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
NSLog(@"%@",filenames);
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
for (Nsstring *path in self.files) {
[names addobject:[[path lastPathComponent] stringByDeletingPathExtension]];
}
self.files = names;
self.files = [names sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
self.tableView.backgroundColor = [UIColor whiteColor];
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"iphonebackground.png"]];
[super viewDidLoad];
[super viewWillAppear:animated];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
// update the filtered array based on the search text
Nsstring *searchText = searchController.searchBar.text;
NSMutableArray *searchResults2 = [self.files mutablecopy];
// strip out all the leading and trailing spaces
Nsstring *strippedString = [searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// break up the search terms (separated by spaces)
NSArray *searchItems = nil;
if (strippedString.length > 0) {
searchItems = [strippedString componentsSeparatedByString:@" "];
}
// build all the "AND" expressions for each value in the searchString
//
NSMutableArray *andMatchPredicates = [NSMutableArray array];
for (Nsstring *searchString in searchItems) {
nspredicate *sPredicate =
[nspredicate predicateWithFormat:@"SELF contains[c] %@",searchString];
[searchResults2 filterUsingPredicate:sPredicate];
// at this OR predicate to our master AND predicate
// NSCompoundPredicate *orMatchPredicates = [NSCompoundPredicate orPredicateWithSubpredicates:searchItemsPredicate];
//[andMatchPredicates addobject:orMatchPredicates];
}
// match up the fields of the Product object
// NSCompoundPredicate *finalCompoundPredicate =
//[NSCompoundPredicate andPredicateWithSubpredicates:andMatchPredicates];
//searchResults2 = [[searchResults filteredArrayUsingPredicate:finalCompoundPredicate] mutablecopy];
// hand over the filtered results to our search results table
APLResultsTableController *tableController = (APLResultsTableController *)self.searchController.searchResultsController;
tableController.filteredProducts = searchResults2;
[tableController.tableView reloadData];
}
- (void)handleSearchForTerm:(Nsstring *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
array = nil;
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (Nsstring *currentString in [self files])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addobject:currentString];
}
}
}
}- (void)viewDidUnload
{
[super viewDidUnload];
// Save the state of the search UI so that it can be restored if the view is re-created.
[self setSavedSearchTerm:[[[self searchdisplayController] searchBar] text]];
[self setSearchResults:nil];
}
- (BOOL)shouldAutorotatetoInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
if( UI_USER_INTERFACE_IdioM() == UIUserInterfaceIdiomPad )
{
// The device is an iPad running iPhone 3.2 or later.
return YES;
}
else
{
// The device is an iPhone or iPod touch.
return YES;
}
#else
// iPhone simulator
return YES;
#endif
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSInteger rows;
rows = [[self files] count];
return rows;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Nsstring *filename = [[[self.files objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension];
NSInteger row = [indexPath row];
Nsstring *contentForThisRow = nil;
contentForThisRow = filename;
static Nsstring *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[[cell textLabel] setText:contentForThisRow];
cell.textLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:90];
cell.textLabel.textColor = [UIColor blackColor];
cell.backgroundColor = [UIColor lightGrayColor];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if( UI_USER_INTERFACE_IdioM() == UIUserInterfaceIdiomPad ) {
return 80;
}
else {
return 120;
}
}
- (void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
{
//this gives you the indexpath of the focused cell
NSIndexPath *nextIndexPath = [context nextFocusedindexPath];
NSLog(@"Do Something");
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedCountry = (tableView == self.tableView) ?
self.files[indexPath.row] : self.resultsTableController.filteredProducts[indexPath.row];
[self performSegueWithIdentifier:@"ShowSong" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"ShowSong"])
{
NSLog(@"Selecting %@",self.selectedCountry);
FirstViewController* userViewController = [segue destinationViewController];
userViewController.selectedCountry = self.selectedCountry;
//if you need to pass data to the next controller do it here
}
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data,images,etc. that aren't in use.
}
- (void)dealloc {
}
@end
现在是打开代码:
@implementation FirstViewController
- (CGPDFDocumentRef)openPDFLocal:(Nsstring *)pdfURL {
NSURL* NSUrl = [NSURL fileURLWithPath:pdfURL];
return [self openPDF:NSUrl];
}
- (CGPDFDocumentRef)openPDFURL:(Nsstring *)pdfURL {
NSURL* NSUrl= [NSURL URLWithString:pdfURL];
return [self openPDF:NSUrl];
}
- (CGPDFDocumentRef)openPDF:(NSURL*)NSUrl {
CFURLRef url = (CFURLRef)CFBridgingRetain(NSUrl);
CGPDFDocumentRef myDocument;
myDocument = CGPDFDocumentCreateWithURL(url);
if (myDocument == NULL) {
NSLog(@"can't open %@",NSUrl);
CFRelease (url);
return nil;
}
CFRelease (url);
if (CGPDFDocumentGetNumberOfPages(myDocument) == 0) {
CGPDFDocumentRelease(myDocument);
return nil;
}
return myDocument;
}
- (void)drawDocument:(CGPDFDocumentRef)pdfDocument
{
// Get the total number of pages for the whole PDF document
int totalPages= (int)CGPDFDocumentGetNumberOfPages(pdfDocument);
self.pages = totalPages;
NSMutableArray *pageImages = [[NSMutableArray alloc] init];
// Iterate through the pages and add each page image to an array
for (int i = 1; i <= totalPages; i++) {
// Get the first page of the PDF document
CGpdfpageRef page = CGPDFDocumentGetPage(pdfDocument,i);
CGRect pageRect = CGpdfpageGetBoxRect(page,kCGPDFMediaBox);
// Begin the image context with the page size
// Also get the grapgics context that we will draw to
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// Rotate the page,so it displays correctly
CGContextTranslateCTM(context,0.0,pageRect.size.height);
CGContextScaleCTM(context,1.0,-1.0);
CGContextConcatCTM(context,CGpdfpageGetDrawingTransform(page,kCGPDFMediaBox,pageRect,true));
// Draw to the graphics context
CGContextDrawpdfpage(context,page);
// Get an image of the graphics context
UIImage *image = UIGraphicsGetimageFromCurrentimageContext();
UIGraphicsEndImageContext();
[pageImages addobject:image];
}
// Set the image of the PDF to the current view
[self addImagesToScrollView:pageImages];
}
-(void)addImagesToScrollView:(NSMutableArray*)imageArray {
int heigth = 0;
for (UIImage *image in imageArray) {
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame=CGRectMake(200,heigth,1520,1080);
[_scrollView addSubview:imgView];
heigth += imgView.frame.size.height;
}
}
-(void)viewDidLayoutSubviews {
NSLog(@"%ld",(long)self.pages);
_scrollView.contentSize = CGSizeMake(1920,1080*self.pages);
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"DOCUMENTS%@",self.selectedCountry);
Nsstring *testing = [self.selectedCountry stringByAppendingString:@".pdf"];
//This is passed in from a tableview after selecting the PDF needed.
_scrollView.panGestureRecognizer.allowedTouchTypes = @[ @(UITouchTypeIndirect) ];
Nsstring *Documents = [[NSBundle mainBundle] pathForResource:self.selectedCountry ofType:@"pdf" inDirectory:@"aimPDF"];
NSLog(@"OKOKOK%@",Documents);
NSURL *url = [NSURL fileURLWithPath:Documents];
self.view.backgroundColor = [UIColor blackColor];
CGPDFDocumentRef pdfDocument = [self openPDF:url];
[self drawDocument:pdfDocument];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// dispose of any resources that can be recreated.
}
@end
解决方法
在您的情况下,搜索视图控制器位于应用程序的顶层,这就是通过按 Menu 按钮而不是返回开始屏幕来关闭应用程序的原因。在 tvOS
上,您不应直接使用 UISearchController
并调用
[self.searchController.searchBar becomeFirstResponder];
或 self.searchController.active = YES;
来呈现搜索,因为它打破了堆叠的视图层次结构,允许您通过呈现的视图控制器向上导航。
在 Apple TV 上,人们通常通过在堆叠的内容屏幕中移动来导航。每个屏幕都可以显示其他屏幕的入口点,并提供一种方法——通过遥控器——返回上一个屏幕或主菜单。 https://developer.apple.com/design/human-interface-guidelines/tvos/app-architecture/navigation/
有 UISearchContainerViewController
视图控制器可以管理界面中搜索结果的呈现,您可以使用它进行搜索:
在 tvOS 中,与其将 UISearchController 推送到导航控制器的堆栈上或将其用作另一个容器视图控制器的子项,不如嵌入此类的实例并让它管理搜索控制器内容的呈现。 https://developer.apple.com/documentation/uikit/uisearchcontainerviewcontroller
例如:
UITableViewController* searchTableViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SearchTableViewController"];
UISearchController* searchController = [[UISearchController alloc] initWithSearchResultsController:searchTableViewController];
searchController.delegate = self;
searchController.searchResultsUpdater = self;
searchController.searchBar.delegate = self;
self.searchContainerViewController = [[UISearchContainerViewController alloc] initWithSearchController:searchController];
// Show searching
[self presentViewController:self.searchContainerViewController animated:YES completion:nil];