Re: nextKeyView order is ignored after loading into NSTabView
Re: nextKeyView order is ignored after loading into NSTabView
- Subject: Re: nextKeyView order is ignored after loading into NSTabView
- From: Steve Mills <email@hidden>
- Date: Wed, 04 Dec 2013 10:12:24 -0600
On Dec 4, 2013, at 01:50:22, Kyle Sluder <email@hidden> wrote:
> As far as the tab view goes, the tab view mucks with the key view loop
> of the to-be-selected item's view whenever its current tab item changes.
> If the initial first responder is set then it works as you expect,
> *except* that the last view in the loop has its nextKeyView set to the
> tab view itself. This normally has no visible effect, since the tab view
> returns NO from -acceptsFirstResponder and returns the correct value
> from -nextKeyView such that -nextValidKeyView remains a loop.
>
> I presume NSTabView insists on inserting itself into the key view loop
> in order to ensure that a user who is using Full Keyboard Access is able
> to navigate to the tab view and from there to its peers, rather than
> being trapped inside the tab view's content area (which is a failure
> mode I have experienced when using VoiceOver on iOS).
Aha! The existing code was setting the initialFirstResponder to the first field in the tab1 view, but I had temporarily commented it out to try to figure out where the order was getting hosed. In the mean time I'd added code to build a list of the key view order before the tab1 view got moved into the NSTabView, and then restored that order afterward. But the order didn't stick.
So, I uncommented the setInitialFirstResponder line AND inserted the NSTabView into the front of my saved order list, and now it's working like it should have all along, before the NSTabView tried to be clever and royally mess everything up. I tested it with the system pref set to Fields & Lists and All Controls. Thanks for the research and info that helped me understand how this mess works.
It looks something like this (minus the stupid 8-space tabs that Mail *still* insists on using). It's very specific to this one dialog, but the gist is there. I should be able to extract a generic algorithm if the need arises for another dlog in the future:
NSTabViewItem* fileInfoTab = [m_dlg->tabs tabViewItemAtIndex:tabIndex];
std::vector<NSView*> tabOrder;
NSView* view = m_fileInfoView->m_viewController.titleField;
tabOrder.push_back(m_dlg->tabs); // The tab view itself should be the first item in the chain.
do {
tabOrder.push_back(view);
view = [view nextKeyView];
} while(view != m_fileInfoView->m_viewController.titleField);
fileInfoTab.view = m_fileInfoView->m_viewController.view;
[fileInfoTab setInitialFirstResponder:m_fileInfoView->m_viewController.titleField];
if(tabOrder.size() > 1) {
std::vector<NSView*>::const_iterator endIt = tabOrder.end() - 1;
for(std::vector<NSView*>::const_iterator it = tabOrder.begin(); it != tabOrder.end(); it++) {
std::vector<NSView*>::const_iterator nextIt;
if(it == endIt)
nextIt = tabOrder.begin();
else
nextIt = it + 1;
[*it setNextKeyView:*nextIt];
}
}
--
Steve Mills
office: 952-818-3871
home: 952-401-6255
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden