ios 导航tvOS UITableView按字母顺序

jogvjijk  于 2023-08-08  发布在  iOS
关注(0)|答案(1)|浏览(111)

bounty将在23小时后到期。回答此问题可获得+400声望奖励。user717452希望引起更多关注此问题。

这是YouTube上的一段视频。Video
我有一个UITableView,它按字母顺序列出了应用程序中的文件。由于有超过1500个文件,我试图实现功能,以浏览字母表中的字母时,右键单击遥控器。我遇到的问题是,TableView确实移动到了正确的位置,但不是像通常那样突出显示,而是得到一个较浅的突出显示颜色,单击select什么也不做。如果我然后通过按下正常导航,它会将其向上移动到列表中的第2个项目。我做错了什么?

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.delegate = self;
      self.tableView.dataSource = self;
    self.definesPresentationContext = YES;  // know where you want UISearchController to be displayed
    self.currentIndex = 0;
   
    [self populateTheView];
}

- (void)populateTheView {
    NSBundle *bundle = [NSBundle mainBundle];
    self.title = @"Devo Songs";
    self.files  = [bundle pathsForResourcesOfType:@"pdf" inDirectory:@"WorshipSongs"];
    NSString *documentsDirectoryPath = [self.files objectAtIndex:thepath.row];
    
    self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
      
    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:)];
    NSLog(@"FILESLOAD%@", self.files);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [self becomeFirstResponder]; // Make the view controller the first responder to handle remote control events.
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

// Override pressesBegan method to detect right arrow key press event.
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
    [super pressesEnded:presses withEvent:event];

    for (UIPress *press in presses) {
        if (press.type == UIPressTypeRightArrow) {
            [self handleRightButtonPress];
        }
    }
}

- (void)handleRightButtonPress {
    // Get the current name.
    NSString *currentName = self.files[self.currentIndex];

    // Get the current letter.
    NSString *currentLetter = [currentName substringToIndex:1];

    // Find the next index starting from the current index.
    NSInteger nextIndex = self.currentIndex + 1;
    while (nextIndex < self.files.count) {
        NSString *nextName = self.files[nextIndex];
        NSString *nextLetter = [nextName substringToIndex:1];

        if (![nextLetter isEqualToString:currentLetter]) {
            break;
        }

        nextIndex++;
    }

    // Check if we found a valid next index.
    if (nextIndex < self.files.count) {
        // Scroll the table view to the row corresponding to the next letter.
        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:nextIndex inSection:0]
                              atScrollPosition:UITableViewScrollPositionTop animated:NO];

        // Update the current index to the new index.
        self.currentIndex = nextIndex;
        
        // Deselect the current selected row (if any).
        NSIndexPath *previousSelectedIndexPath = [self.tableView indexPathForSelectedRow];
        if (previousSelectedIndexPath) {
            [self.tableView deselectRowAtIndexPath:previousSelectedIndexPath animated:NO];
        }

        // Select the cell at the specified index.
        NSIndexPath *indexPathToSelect = [NSIndexPath indexPathForRow:self.currentIndex inSection:0];
        [self.tableView selectRowAtIndexPath:indexPathToSelect animated:NO scrollPosition:UITableViewScrollPositionNone];
    } else {
        // If we have reached the end of the list, reset the index to the first element.
        self.currentIndex = 0;

        // Scroll back to the top of the table view.
        [self.tableView setContentOffset:CGPointZero animated:NO];

        // Deselect the current selected row (if any).
        NSIndexPath *previousSelectedIndexPath = [self.tableView indexPathForSelectedRow];
        if (previousSelectedIndexPath) {
            [self.tableView deselectRowAtIndexPath:previousSelectedIndexPath animated:NO];
        }

        // Select the cell at the specified index.
        NSIndexPath *indexPathToSelect = [NSIndexPath indexPathForRow:self.currentIndex inSection:0];
        [self.tableView selectRowAtIndexPath:indexPathToSelect animated:NO scrollPosition:UITableViewScrollPositionNone];
    }
}

字符串
不确定是否需要,但应用程序的主要场景是一个标签栏控制器。它总共有两个选项卡,左边的一个在启动时显示的是Split View,第二个是这里讨论的一个,它只是一个UITableViewController,并通过故事板中的segue呈现。100d1x

的字符串

yruzcnhs

yruzcnhs1#

好了,系好安全带孩子!我们将为您已经非常出色的代码添加一些魔力!
你看,与iOS相比,tvOS有点不同。它有自己的焦点模型,就像舞台上神奇的聚光灯,总是试图一次把一个界面元素(我们的演员)放在聚光灯下。现在,您已经在以编程方式滚动和选择单元格方面做了出色的工作,但聚光灯...呃,注意力不太集中。但别担心,我们有锦囊妙计!这叫焦点指南
把这位焦点导播当成我们这出戏的导演。它将帮助我们准确地告诉聚光灯下该去哪里。
首先,让我们在viewDidLoad方法中创建一个新的Focus Guide,并铺上红地毯来引导我们的聚光灯:

self.dapperFocusGuide = [[UIFocusGuide alloc] init];
[self.view addLayoutGuide:self.dapperFocusGuide];

// Alright, red carpet time.
[self.dapperFocusGuide.topAnchor constraintEqualToAnchor:self.tableView.topAnchor].active = YES;
[self.dapperFocusGuide.leftAnchor constraintEqualToAnchor:self.tableView.leftAnchor].active = YES;
[self.dapperFocusGuide.widthAnchor constraintEqualToAnchor:self.tableView.widthAnchor].active = YES;
[self.dapperFocusGuide.heightAnchor constraintEqualToAnchor:self.tableView.heightAnchor].active = YES;

字符串
接下来,让我们告诉我们的导演,哪一个演员需要在戏剧开始时的聚光灯下:

self.dapperFocusGuide.preferredFocusEnvironments = @[self.tableView.visibleCells.firstObject];


现在,抓住你的帽子,因为我们要教我们的导演一些新技巧!我们将告诉它如何在handleRightButtonPress方法中处理脚本中的更改:

// Rest of your spectacular code...

// Select the cell at the specified index.
NSIndexPath *indexPathToSelect = [NSIndexPath indexPathForRow:self.currentIndex inSection:0];
[self.tableView selectRowAtIndexPath:indexPathToSelect animated:NO scrollPosition:UITableViewScrollPositionNone];

// And now, the moment we've all been waiting for. Drumroll please... 
// Let's tell our director to shift the spotlight!
UITableViewCell *cellToFocus = [self.tableView cellForRowAtIndexPath:indexPathToSelect];
self.dapperFocusGuide.preferredFocusEnvironments = @[cellToFocus];


现在,别忘了告诉编译器我们都是剧院人员,并导入UIFocusGuide
有了这些,当您按下右键时,tableView现在应该正确地聚焦在正确的单元格上。这就像是代码和UI之间精心编排的舞蹈。来吧,鞠个躬!你应得的!🎭👏🎉
这是所有的东西放在一起。。

#import <UIKit/UIFocusGuide.h>

@interface YourTableViewController ()
@property (nonatomic, strong) NSArray *files;
@property (nonatomic, strong) NSString *filenames;
@property (nonatomic, strong) UIFocusGuide *dapperFocusGuide;
@property (nonatomic, assign) NSInteger currentIndex;
@end

@implementation YourTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // We're setting the stage!
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.definesPresentationContext = YES;
    self.currentIndex = 0;

    // Time to call the stars for a rehearsal.
    [self populateTheView];
    
    // Let's make room for our magical focus director.
    self.dapperFocusGuide = [[UIFocusGuide alloc] init];
    [self.view addLayoutGuide:self.dapperFocusGuide];

    // Red carpet time!
    [self.dapperFocusGuide.topAnchor constraintEqualToAnchor:self.tableView.topAnchor].active = YES;
    [self.dapperFocusGuide.leftAnchor constraintEqualToAnchor:self.tableView.leftAnchor].active = YES;
    [self.dapperFocusGuide.widthAnchor constraintEqualToAnchor:self.tableView.widthAnchor].active = YES;
    [self.dapperFocusGuide.heightAnchor constraintEqualToAnchor:self.tableView.heightAnchor].active = YES;
}

- (void)populateTheView {
    NSBundle *bundle = [NSBundle mainBundle];
    self.title = @"Devo Songs";
    self.files  = [bundle pathsForResourcesOfType:@"pdf" inDirectory:@"WorshipSongs"];
    NSString *documentsDirectoryPath = [self.files objectAtIndex:self.currentIndex];
    
    self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
      
    NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
    for (NSString *path in self.files) {
        [names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
    }
   
    self.files = [names sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    NSLog(@"FILESLOAD%@", self.files);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    // Cue the music! The show has started.
    [self becomeFirstResponder]; 

    // Initial spotlight position.
    self.dapperFocusGuide.preferredFocusEnvironments = @[self.tableView.visibleCells.firstObject];
}

- (BOOL)canBecomeFirstResponder {
    return YES; // Of course we can! We're the star of the show!
}

// Here we keep an eye out for any new script changes (aka right arrow key press events).
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
    [super pressesEnded:presses withEvent:event];

    for (UIPress *press in presses) {
        if (press.type == UIPressTypeRightArrow) {
            [self handleRightButtonPress];
        }
    }
}

- (void)handleRightButtonPress {
    // Your logic here to find the next index...

    // Get the newly called star ready for the scene.
    NSIndexPath *indexPathToSelect = [NSIndexPath indexPathForRow:self.currentIndex inSection:0];
    [self.tableView selectRowAtIndexPath:indexPathToSelect animated:NO scrollPosition:UITableViewScrollPositionNone];

    // And now, the moment we've all been waiting for. Drumroll please... 
    // The spotlight moves!
    UITableViewCell *cellToFocus = [self.tableView cellForRowAtIndexPath:indexPathToSelect];
    self.dapperFocusGuide.preferredFocusEnvironments = @[cellToFocus];
}

// Here you would have your other UITableViewDelegate and UITableViewDataSource methods...

@end

相关问题