ButtonBarPagerTabStripViewController updateIndicator toIndex is wrong - ios

I need to add or remove items from the navigation bar when the user changes screen so I have a code like:
override func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) {
super.updateIndicator(for: viewController, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: progressPercentage, indexWasChanged: indexWasChanged)
if indexWasChanged {
if toIndex == 2 {
rightBtn.alpha = 1
} else {
rightBtn.alpha = 0
}
}
}
rightBtn is simply a button on the right end of my navigation bar.
However during my testing runs I noticed that if the user taps on the ButtonBar instead of swiping to change screen, the fromIndex and toIndex is wrong. It will still be the values of the last change.
E.g. when the user swipes from the third screen to the second, the fromIndex will be 2 and toIndex 1 but if the user taps on the third button on the bar, the fromIndex will still be 2 even though it is expected to be at 1 the toIndex will also stay at 1 even though now it should be 2.
This results in my rightBtn not showing if the user swipes from the third screen then taps the bar back to the third.
Is there a way to obtain the correct toIndex during such a scenario or can it be fixed?
The first part is the buggy part where I navigate by tapping directly on the barbutton, the second part without the pointer is navigation by swiping with works fine, the Icon is only suppose to appear on the Third Tab

I have gotten a solution, for anyone with the same problem, there is a currentIndex in ButtonBarPagerTabStripViewController. So this:
if indexWasChanged {
if currentIndex == 2 {
rightBtn.alpha = 1
} else {
rightBtn.alpha = 0
}
}
will work over the original codes in the question.
Also I went to the GitHub project and found that someone else who is facing this problem already reported it. Hopefully it will be fixed and both methods will work.

Related

Swift/Xcode: Why does the tab bar disapear if I navigate away from the page?

So I have a list of exercises. Each exercise is a button that segues to a screen that shows a video of the exercise. I then have a back button on the video page that segues back to the initial list of exercise page. However, when I segue back, the tab bar at the bottom is no longer there. Any idea why it's disapearing? Thanks so much!
Sorry about last answer it was for some other question on stackoverflow just misplaced it. Please take a look in your on video page controller if you have this selected. Also check if you have these lines in your code
self.hidesBottomBarWhenPushed = YES;
Change your segue to perform segue to TAB BAR CONTROLLER
Create a UITabBarController file. Inside it , create a struct and a simple if condition
class TabBarController: UITabBarController {
struct defaultIndexSelection {
static var selectedIndex = "0"
}
override func viewDidLoad() {
super.viewDidLoad()
if defaultIndexSelection.selectedIndex == "0"
{
self.tabBarController?.selectedIndex = 0
}
else if defaultIndexSelection.selectedIndex == "1"
{
self.tabBarController?.selectedIndex = 1
}
else if defaultIndexSelection.selectedIndex == "2"
{
self.tabBarController?.selectedIndex = 2
}
else if defaultIndexSelection.selectedIndex == "3"
{
self.tabBarController?.selectedIndex = 3
}
}
Set this TabBarController as the class of your TabBarController.
Now on your back buttons action , add this line.
TabBarController.defaultIndexSelection.selectedIndex = 0
// if you want to have the tab at index 0 selected and
shown on back button press or 1 if you want first tab selected
Thats it, whenever you press back from whatever viewController, it will segue back to tabbarcontroller and then select the index depending on which viewcontroller you came from.
TabBarController.defaultIndexSelection.selectedIndex = 0 being your 1st tab
TabBarController.defaultIndexSelection.selectedIndex = 1 being your 2nd tab
TabBarController.defaultIndexSelection.selectedIndex = 2 being your 3rd tab
TabBarController.defaultIndexSelection.selectedIndex = 3 being your 4th tab

Why am I getting this error: fatal error - array index out of range?

I have 2 view controllers: a cameraVC and a detailVC. The camera is an AVFoundation camera that can capture and then select pictures, which then populates 4 small imageViews on my detailVC. I am trying to swipe between the two VCs so that when you hit 'yes' on the cameraVC, that then adds that to one of the 4 imageViews. I am currently using for-loops to achieve this, and below is the code I have in my detail VCs.
It works when I first load the app and take a few pics, but when I swipe back to my cameraVC and then back to my detailVC, the app crashes and logs error above.
In my code, I am attempting to set the imageViewArray to however many images there are in my imageArray. Then each time I go back to the detailVC, I am to clear my imageView.images and re-assign them. For some reason, it's not working. Any ideas why?
override func viewWillAppear(animated: Bool) {
if imageArray.count == 1 {
imageViewArray += [imageView1]
} else if imageArray.count == 2 {
imageViewArray += [imageView1,imageView2]
} else if imageArray.count == 3 {
imageViewArray += [imageView1,imageView2,imageView3]
} else if imageArray.count == 4 {
imageViewArray += [imageView1,imageView2,imageView3,imageView4]
}
for ima in imageViewArray {
if ima.image != nil {
ima.image = nil
}
}
for (index, imageView) in imageViewArray.enumerate() {
imageView.image = imageArray[index]
}
}
Add the line
imageViewArray = []
in the beginning of your viewWillAppear.
Or change your assignment to the imageViewArray in all 4 branches to something like:
imageViewArray = [imageView1,imageView2,imageView3,imageView4] // removed the "+"
The problem you are encountering here is that the method gets called when the view gets presented the first time AND when some presented view gets dismissed / popped again causing your view to appear again.
The result of that is that the imageViewArray still contains the imageviews from the last iteration. Adding the images again causes the array to get larger.
Assume that you had 3 images the first time, now the second time you have 4 images. Therefore you enter the last else section and add 4 new elements to the array, causing it to have 7 elements while the imageArray still only has 4. Now you iterate over all imageViewArray entries and try to access the imageArray at up to index 6 while the array only contains value until index 3 -> crash.
Note that it was annoying writing this answer because you have too many variables that all sound and look the same imageView, image, imageArray, imageViewArray, ima, imageViewX. Please try to find better names.

Segue on Swipe on last page of UIPageView

I have a PageViewController with 3 pages. I want to segue away from PageViewController to AnotherViewController when user swipes from right to left on the last page. I cant figure out how to do it.
The only trigger for swipe is
func viewControllerAtIndex(index : Int) -> UIViewController?
and looking for index == 3 and then perform the segue BUT index == 3 never reaches because there is no 4th page? What am I missing?
There is no index 3. The last index is 2. Because it starts from 0 - 1 -2.

UITableView:reloadSectionIndexTitles animated correct way

I am trying to hide the index bar of a UITableView while scrolling.
Therefore I am reloading the section index titles when I start scrolling and when finish. Returning an empty array hides the bar.
My code is:
var showSectionIndexTitles = true
override func scrollViewWillBeginDragging(scrollView: UIScrollView) {
showSectionIndexTitles = false
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.tableView.reloadSectionIndexTitles()
})
}
override func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
showSectionIndexTitles = true
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.tableView.reloadSectionIndexTitles()
})
}
override func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! {
if showSectionIndexTitles {
return uniq([UITableViewIndexSearch] + AlphabetUppercase + datamanager.categoryIndexTitles)
} else {
return nil
}
}
This works when using no animations, but I would like to use an animation.
I would prefer an animation where the whole bar moves out to the right when the bar is hidden and move in from the right when the bar is visible
I tried to use UIView:animateWithDuration to test if an animation is possible at all.
What I have noticed:
This basic animation moves/scales in from the left top corner when
visible
When hiding the bar it disappears instantly
My questions:
What is the best way of achieving an animation for indexbar visibility?
What is the best way of achieving the particular animation I mentioned earlier?
Thank you in advance!
EDIT 1:
I just remembered where I have seen this effect before: iOS 8.4 Music App
Apple does the same when you scroll so far that you can only see the title list(UITableView)
EDIT 2:
I filed a bug report to apple suggesting a function for changing visibility of the index bar with a animated parameter. I am going to inform you as soon as I get a response.
Even though #matt already suggested a possible solution in his answer, still if anybody else knows a different convenient way of solving this problem or has also faced this kind of feature in the past I would be glad to hear from you!
What you're trying to do is unsupported. Therefore there is no "best" or "correct" way - whatever you do will be an illegal hack. What I would do is snapshot the index bar, hide the real index bar as you are already doing (i.e. legally and normally), and animate the snapshot.

Thread 1: EXC_BAD_ACCESS (code=2, address=0x7fff59d8dff8)

What I'm trying to do:
The following bit of code is for 2 buttons on a page. This page is part of an array of pages (which is stored in self.parent; it also stores the index it has in that said array in self.index).
The 2 buttons are used to navigate forwards and backwards in this array of pages. If it tries to go forward but hits the end of the array, it should go back to the first page; Likewise for going back and hitting the beginning of the array.
#IBAction func previousButton(sender: AnyObject) {
self.prev()
}
#IBAction func nextButton(sender: AnyObject) {
self.next()
}
func next(){
if let _parent = self.parent{
if self.index != _parent.getSize()-1 {
self.view.addSubview(_parent[self.index+1].view)
}
else{
self.view.addSubview(_parent[0].view)
}
}
else{
println("This Page is not part of a List")
}
}
func prev(){
if let _parent = self.parent{
if self.index != 0 {
self.view.addSubview(_parent[self.index-1].view)
}
else{
self.view.addSubview(_parent[_parent.getSize()-1].view)
}
}
else{
println("This Page is not part of a List")
}
}
Problem is:
EDIT: The crashes have nothing to do with the if statements and it isn't random either; It crashes when I hit the next button for the tenth time, the previous button for the tenth time (ten is the number of pages I have in my list; if I add more pages, this number changes accordingly), and when I press prev after pressing next OR pressing next after pressing next.
I figured out the problem: I am not properly switching between pages, I am just adding one on top of the others; The crash occurs when I attempt to show a page that was already loaded (and still is somewhere beneath the stack of pages).
Now I need to find a better way to switch between them.
Make sure you have the same class name in StoryBoard and in ViewController

Resources