UIFocusGuide doesn't work on UICollectionView in tvOS - uicollectionview

Basing on this post:
UICollectionViewCell to UIButton Focus in tvOS, I'm adding a UIFocusGuide so when the user are on the right of the collectionview, can select the button on left-buttom.
Using this code:
focusGuide = UIFocusGuide();
focusGuide.preferredFocusedView = btClick
view.addLayoutGuide(focusGuide)
focusGuide.topAnchor.constraintEqualToAnchor(collectionView.topAnchor).active = true
focusGuide.bottomAnchor.constraintEqualToAnchor(btClick.bottomAnchor).active = true
focusGuide.leadingAnchor.constraintEqualToAnchor(collectionView.leadingAnchor).active = true
focusGuide.widthAnchor.constraintEqualToAnchor(collectionView.widthAnchor).active = true
In my example I added a usefull code created by Jack Cox that shows the 'invisible' layout guides, and everything seems good because the layout begin on the top of the collectionView and ends on the bottom of the button.
But it doesn't works, the button only can be selected if the user are on the left of collectionView, on this image you can only going to button from item 1 and item 6.
I've made a little example on github here, I don't know what I'm doing wrong.

I have already figured out, the mistake was to create the focus with the entire size of the collectionView now I've created a focus guide just below the collectionView and set preferredFocusedViewto the button.
Using this code:
focusGuide = UIFocusGuide();
focusGuide.preferredFocusedView = btClick
view.addLayoutGuide(focusGuide)
//Modified the size of the UIFocusGuide
focusGuide.topAnchor.constraintEqualToAnchor(btClick.topAnchor).active = true
focusGuide.rightAnchor.constraintEqualToAnchor(collectionView.rightAnchor).active = true
focusGuide.widthAnchor.constraintEqualToAnchor(btClick.widthAnchor, multiplier: 8).active = true
focusGuide.heightAnchor.constraintEqualToAnchor(btClick.heightAnchor).active = true
Now the guide look like this:
I've just committ the changes to github maybe it helps anyone else.

Related

iOS UI Testing cannot see the UILabel

I have a UI testing issue with some code I've got from another developer (Whose not with the project anymore). The code display a simple alert box at the top of the screen when there's an error and I cannot get my UI test to see the UILabel within it.
The structure of the box looks like this:
UIView
+ UILabel
+ UIButton
And in the custom class for the UIView there is this code:
// Original code
accessibilityIdentifier = "AlertBar" // Required for UI Testing.
// Bits I've added trying to make messageLabel visible to UI Test
isAccessibilityElement = true
accessibilityElements = [messageLabel]
messageLabel.accessibilityIdentifier = "AlertBarMessage"
messageLabel.isAccessibilityElement = true
}
If I breakpoint in the middle of my UI Test and dump the app into the log I can see the UIView:
Attributes: Application, pid: 60317, label: 'The App'
Element subtree:
→Application, 0x600001df8c40, pid: 60317, label: 'The App'
Window (Main), 0x600001dfa060, {{0.0, 0.0}, {390.0, 844.0}}
... app ui logged here!
Other, 0x600001dce220, {{4.0, 47.0}, {382.0, 107.7}}, identifier: 'AlertBar'
So it's clear that the alert is visible to XCTest, but nothing inside it. As you can tell from my added code I've been trying all sorts of things but so far I've not been able to make the UILabel (AlertBarMessage) visible.
What am I missing?
As per usual, after typing up a stackOVerFlow question I go back to the code and figure out the problem :-) In this case it was the isAccessibilityElement = true on the view. Making it accessible was effectively hiding the nested UILabel so turning it off fixed my test.
I know there are ways in Accessibility to setup the view correctly for accessibility so that screen readers see it as a single element and can read the message, but I'll have to work on that later for now.

tvOS: Focus first button as preferred focus view when buttons are in horizontal order

I have been trying to focus the first button but focus engine takes the third button right below the tab bar as the first item to be focussed. I tried with preferred focus view but found that when i place the buttons in vertical order then preferred takes the preferred view to be focussed but when i placed all the buttons in horizontal plane it always takes the third button.The other approach i can think of if Focus Guide but i wonder how that will work in this scenario?
override weak var preferredFocusedView: UIView? {
get {
return thrirdButton
}
}
It happens because focus engine takes the nearest possible focus element as 1st element as you can see from the picture attached.I have attached the context screenshot for the view controller. Any help or clue to solve this will be appreciated.
Solution :
We need to add focus guide just above button 3 and redirect it to button one when the focus guide is focussed.
private var focusGuide = UIFocusGuide()
self.view.addLayoutGuide(focusGuide)
self.focusGuide.bottomAnchor.constraintEqualToAnchor(self.button3.topAnchor).active = true
self.focusGuide.leftAnchor.constraintEqualToAnchor(self.button3.leftAnchor).active = true
// Width and height
self.focusGuide.widthAnchor.constraintEqualToAnchor(self.button3.widthAnchor).active = true
self.focusGuide.heightAnchor.constraintEqualToAnchor(self.button3.heightAnchor).active = true
focusGuide.centerXAnchor.constraintEqualToAnchor(self.button3.centerXAnchor).active = true
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
self.focusGuide.preferredFocusedView = button1
}
Try adding a UIFocusGuide just above the button rows. In that case, before reaching the button, it will hit your focus guide in which you can redirect the preferredFocusedView to that particular button. The code to redirect is to be done by overriding didUpdateFocusInContext method.
Assuming you have setup the focus guide in viewDidload, the following is a sample,
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator)
self.focusGuide.preferredFocusedView = self.mypreferredbutton
}
TO initialise a focus guide ( Do the addition of guide to view in viewDidLoad)
var focusGuide = UIFocusGuide()
self.view.addLayoutGuide(self.sidefocusGuide)
self.focusGuide.leftAnchor.constraintEqualToAnchor(self.placerLabel.leftAnchor).active = true
self.focusGuide.rightAnchor.constraintEqualToAnchor(self.placerLabel.rightAnchor).active = true
self.focusGuide.topAnchor.constraintEqualToAnchor(self.audioTable.topAnchor).active = true
I too faced a similar issue but somehow able to do it through this. The preferredFocusedView approach will also work, but you have to do lot of circus by updating some reference variable and then calling setneedsfocusupdate for that view. Try the focus guide way. Hope it helps.
EDITED:
I have added code how to setup the guide. In this case I have put the guide on the right side of my view. So, whenever your focus hits the guide, it redirects to the preferredfocusguide view that you want the focus to go to in the didUpdateFocusInContext. "There is only one view in focus at anytime.", remember thes ? So, the moment it hits the guide, the overriden method gets hit which in turn moves your focus to the guide's preferred view. For examples, you can refer to Apple's UIKitCatlog app for tvOS and here is one link explaining the same.
The best way to give the initial focus to your preferred view is by using preferredFocusEnivronments.
override var preferredFocusEnvironments: [UIFocusEnvironment] {
return [firstButton]
}
preferredFocusEnvironments will be called before didUpdateFocus, that way you can inform the system, where you want the focus to be redirected.

AppBarButton.Icon doesn't change on runtime

I have a problem updating AppBarButton Icon on runtime depending on some conditions.
<AppBarButton x:Name="WeekButton" Click="OnClick" Label="SomeText"
</AppBarButton>
I'm trying to update Icon property in some code behind with this code
WeekButton.Icon = new FontIcon() { Glyph = Runtime_Value_Here};
But nothing happens. The button doesn't change. But in any random time when the code works, It MAY change the button. I always see, that the Icon is new in code, but not on screen. None of the UpdateLayout helps.
Would appreciate any help.
Thanks
UPDATE:
It seems to not working with FontIcon, as with BitmapIcon changing everything works fine.
Force InvalidateArrange and it works
WeekButton.Icon = new FontIcon() { Glyph = "\uE29B", FontFamily = new FontFamily("Segoe UI Symbol")};
WeekButton.InvalidateArrange();
I believed you already found the solution with bitmap icon.
But some people who reached this page and want to know the solution like me,
Here is using bitmap icon and changing app-bar button icon dynamically.
BitmapIcon _bitmapIcon = new BitmapIcon();
_bitmapIcon.UriSource = new Uri("ms-appx:///Assets/yourBitmapIcon.png");
WeekButton.Icon = _bitmapIcon;
Try using the IconUri in order to give the value.
WeekButton.IconUri = new Uri("/Images/pause.png", UriKind.Relative);
Reference: Disable/Enable applicationbar Button in runtime with event textchanged (Windows Phone)

RadioButtons Highlighting Incorrectly

On my form, I have 4 RadioButtons, each with its appearance set to Button. In my program, I change each of these RadioButton's ForeColour, BackColour and AutoCheck status, as below:
ARadioButton.AutoCheck = False
ARadioButton.BackColor = Color.FromKnownColor(KnownColor.ControlLightLight)
ARadioButton.ForeColor = Color.FromKnownColor(KnownColor.ControlDark)
However, later on, I reset these properties back to default:
ARadioButton.AutoCheck = True
ARadioButton.BackColor = DefaultBackColor
ARadioButton.ForeColor = DefaultForeColor
My issue is that instead of the entire button being highlighted, only the outside is, as shown in the images below.
Originally:
After changes are made and RadioButtons reset to default using code above:
I know this may seem trivial, but I would like the entire RadioButton to be highlighted when the user clicks on the RadioButton, not just the outside.
Is there a way I could somehow reset this?
Try setting the BackColor property to Color.Transparent

auto scroll to the bottom of container in sencha touch 2

I have a view that contains 2 parts:
+ Part 1: an ADD button
+ Part 2: a container LIST that has scroll attribute is auto.
When user clicks on button ADD, the system will add a container to container LIST. User can add as much as they want.
But my container LIST has limit height so I want to scroll to new container that added to container LIST when user clicks ADD button.
Anyone help me. Thanks
I tried to use:
var scroller = pan.getScrollable().getScroller();
scroller.scrollToEnd(true);
But it's not working.
Then I tried another way:
var scroller = pan.getScrollable().getScroller();
scroller.scrollTo(x,y,true);// y = 100000000000
It's work :)
var scroller = myListObject.getScrollable().getScroller();
scroller.scrollToEnd();