iOS UISegmentedControll change selectedIndex smoothly - ios

The UISegmentedControl is placed in the UINavigationBar and has two elements (e.g #"One" and #"Two").
The UIViewController contains a UIScrollView with two pages with horizontal scrolling. The segmented control indicates wich of the pages is currently displayed. I know how this works, but I want to implement it so while scrolling the selected tab changes smoothly.
Just like in the Apple Music app...

So it turns out that setting the selected index of a segmented control is now animatable:
UIView.animateWithDuration(4) {
self.seg.selectedSegmentIndex = 1
}
So they must be doing that, coordinating it with the interactive scrolling of the view by setting the layer speed to 0 and changing the timeOffset, as I explain here: https://stackoverflow.com/a/22677298/341994

Related

UIButton default tap animation inside UITableViewCell

I have a few UIButtons inside UITableViewCells, and all of them are missing default tap animation, however if I long press - animation works. I've found some solutions, like setting type to .system, showsTouchOnHighlight = true, but none of them have helped. What is the problem here?
It's not a "problem" - it's by design.
When you have an object such as a button in a table view or scroll view or collection view, and you "touch" it, the system needs to know whether you are tapping the button or if you want to touch-and-drag to scroll the view that contains the button.
So, the table view (really, the "scroll view part" of the table view), waits to see if you drag your finger or not before it performs any actions.
If you want the button to respond immediately to a touch, you need to set
delaysContentTouches = false
on the containing scroll view(s).
If you search for uibutton inside uitableviewcell delaysContentTouches you should find plenty of discussion on this topic, and various approaches to change the default behavior.
For this problem you can add extension to UIButton and override some methods.
You can check my answer here

How to set VoiceOver initial focus on a UITableView

In our iOS app, we have a screen with a UINavigationController, three UIBarButtonItem in the rightBarButtonItems, a UIView content view with a UITableView subview.
Every time the app gets to the foreground, VoiceOver places the initial focus on the leftmost UIBarButtonItem. We would like to have the focus on either the topmost cell in the UITableView (initial start) or the cell that the user actively selected before the app went to the background.
We have tried to call UIAccessibilityPostNotification() but this only works if we add a delay and that seems very fragile and will be confusing for the user as focus will start on the UIBarButtonItem and then jump.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.75*Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, self.view)
}
This might work.
As far as I know uiaccessibilitypostnotification works well with the delay, even though it is fragile, you can call the method with 0.5 seconds delay in the view did appear method!!!!
There is also another way you can try. Once the view is loaded, disable the accessibility for the bar buttons, and set the accessibility only for the tableview!!! You need to change the accessibilityElements array and the first element in the array should be the table view, and set isAccessibilityElemnt to NO for the other elements to turn off the accessibility!!!!

App Store app view layout

I would like to create a view similar to the App Store's app view on the iPhone :
http://cl.ly/image/0Q1h273v3C00
Basically when you scroll down, part of the header remains fixed at the top :
http://cl.ly/image/3m0I3Y0t1901
Here's the approach I tried, but it doesn't work as expected :
I use a tableView as the 'global view'
In this example, my tableView header would be the top part with the app icon, name ... and UISegmentedControl
Below the header is my regular tableView with cells...
Then, I simply implement the method below :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Keeping the menu always visible when user scrolls
// 155 is the original y position of the menu (UISegmentedControl here)
if (scrollView.contentOffset.y > 155) {
self.menuView.frame = CGRectMake(0,
scrollView.contentOffset.y,
self.menuView.frame.size.width,
self.menuView.frame.size.height);
}
else {
self.menuView.frame = CGRectMake(0,
155,
self.menuView.frame.size.width,
self.menuView.frame.size.height);
}
}
The menu remains at the top position just as I want, but still it's not working as expected :
My tableView section headers overlap the menu when I scroll. The only fix I found is to put the header layer at the top using this code :
self.tableView.tableHeaderView.layer.zPosition = MAXFLOAT;
But now the scrollbar is hidden behind the header, so I'm not satisfied with this either
I also tried to use this call in viewDidLoad and ...viewForHeaderInSection
[self.tableView bringSubviewToFront:self.tableView.tableHeaderView];
but it just doesn't work, since the section headers are always added after the tableView header and I haven't found a way to know when the section headers are added, so I can put them behind the tableView header.
When I scroll down more than the menu's initial position, even though the menu remains fixed at the top, I can't click on it, all the events are going to the tableviewcell behind it.
Finally, I want to be able to keep the same header when I click on the other buttons of the UISegmentedControl, just like in the App Store app view, and just change the content below, but I don't want to include the same header each time in each of my views, I would like to make the header generic.
Does anyone have any ideas on how to tackle the problems I'm facing, or a different approach to this ?
P.S : Youtube does kinda the same thing for the channel view, but their solution is not as good as Apple's, as you can't move the content if you start scrolling from the header.
Thanks for your help!

UIButton Title In .xib Overriding Programmatic Title Change

I am writing an app which loads a view (designed in a .xib) with multiple buttons. When loading the view I set the buttons titles programmatically. I then add the view as a subview. For a fleeting second I see the programatically set titles appear and then they change to the prototype titles in the .xib.
Here is the code:
self.cellPhoneButton.titleLabel.text = person.cellPhone;
self.homePhoneButton.titleLabel.text = person.homePhone;
// Do other stuff with the view
[self.peopleView addSubview:self.personView];
Why do the titles of the buttons revert back to their default content, and why is this not happening to the other components of the page (Labels, Navigation Bar Title, etc.)?
EDIT:
I also tried this code without success:
[self.cellPhoneButton setTitle:person.cellPhone forState:UIControlStateNormal|UIControlStateSelected];
[self.homePhoneButton setTitle:person.homePhone forState:UIControlStateNormal|UIControlStateSelected];
// Do other stuff with the view
[self.peopleView addSubview:self.personView];
You should use [self.homePhoneButton setTitle: forState:]; method to set the UIButton's title. and the state in your case should be UIControlStateNormal which means control state will apply to all the states if you don't specify the others explicitly. If you combine the Normal with others, then Normal will be overidded.

For iOS how do I create a draggable button within a button?

In xCode I'm making an iPad app, and have created a series of counters in UIimageViews that drag around the screen when you touch them. All good so far.
But now I want to have another smaller hidden button just above each counter that is disabled, so that when you tap on the counter the smaller button can appear and can perform an action (such as 'return to starting position' or 'hide'.
I'm just not sure where to go with this one now. Any ideas or hints would be much appreciated!
So you create the buttons and set their frames and add them as sub views to your view. From that point on you can hide them by making their alpha = 0.0, have them appear disabled by setting alpha to say 0.5 (set enabled to NO), and make them live with alpha=1.0. You can animate frame and alpha changes. For convenience you can set their tag properties to a value related to the counter so you can easily get them using viewWithTag:.

Resources