uisegmented control manually setting selected index not working - iphone

Ok so I have a segmentedControl which I need to dynamically remove and add segments to. This piece of code will remove the first segment but then doesnt set the correct segment to be selected. The strange thing is when I print it out all the numbers are correct it is just the highlighted segement on the screen which is always out by -1.
if ([outControl numberOfSegments]==4) {
int previous = [outControl selectedSegmentIndex];
if (previous>0) {
previous--;
}
[outControl removeSegmentAtIndex:0 animated:YES];
NSLog(#"setting to %d with %d segments", previous ,[outControl numberOfSegments]);
[outControl setSelectedSegmentIndex:previous];
}
Here is the log setting to 1 with 3 segments. With this log segment 0 is actually selected in the control and I cannot press segment 1 as the control thinks it is selected?
I can press segment 0 though even though that is the one being displayed as selected.
Here is a screen grab to try and clarify my issue.
image
The text in the cell is correct as cell 1 is actually selected as you can see by the log. But the highlighted cell is 0!? Its driving me crazy. It all works when adding segments its only when removing I get the issue.
Can anyone see where its going wrong??
Many thanks
Jules
I have noticed that even if i do not set the new selected segment I get the same results ie the wrong segment is selected.....?? Also this is all coded with cellForRowAtIndexPath if that helps anyone?

The code looks right yet behaves (wrongly) just as you described. It seems that the control gets in an awkward state when changing the selection in the same turn of the run loop as the segment deletion. But this works:
-(void)setSegmentedSelection:(NSNumber *)indexNum {
NSInteger index = [indexNum intValue];
[outControl setSelectedSegmentIndex:index];
}
// then instead of setting the selected index after the segment is removed,
// let the run loop return...
[self performSelector:#selector(setSegmentedSelection:) withObject:[NSNumber numberWithInt:previous] afterDelay:0.0];
I'm surprised that it doesn't work as you coded, but at least here's a workaround until we figure it out.

Related

Swift Segmented Control default state

I have a segmented control that works lovely if you tap one of the segments BUT if you don't tap anything and let it sit at the natural resting spot which is the first segment it doesnt work
I tested this by tapping another segment and continuing the app and it worked, and i also tested by tapping another segment and then going back to the first segment and it worked
#IBAction func segmentedControl(sender: UISegmentedControl) {
switch segmenControl.selectedSegmentIndex {
case 0:
numberOfParticipants = "4"
case 1:
numberOfParticipants = "6"
case 2:
numberOfParticipants = "8"
case 3:
numberOfParticipants = "10"
case 4:
numberOfParticipants = "12"
case 5:
numberOfParticipants = "14"
case 6:
numberOfParticipants = "16"
default:
break
}
}
It makes sense since it is wrapped in an IBAction and nothing is being pressed therefore it's not being triggered. How do i fix this issue?
Edit
By doesn't work i mean if the segment that is highlighted says 4 AND the user taps a continue button (different button) then a variable gets updated with a string of "4" and then firebase gets updated to say x = 4
So what is happening is when you land on the page by default the 4 segment is highlighted and if you want 4 to be your option you would leave it alone and hit the continue button...my problem is that if you don't interact with the segment control and actually tap 4 then the code never gets run, but if you tapped 6 then back to 4 it would trigger
Your questions in not very clear in defining what exactly seems to be broken. What doesn't work if you don't tap it? In general there are 2 steps involved in using UISegmentedControls. In step 1 you set it in your initialization - i.e. viewDidLoad - via:
segmenControl.selectedSegmentIndex = your_initial_value
Of course your initial value cannot be numberOfParticipants because the control only has 6 values..
Then step 2 is something like your IBAction which looks fine. Your use of magic numbers is of course a bit problematic.
This is how I understand the question:
You have a "Continue" button and if you hit it, you want it to reflect the state of the segmented control. Correct?
If that's the case, you don't need the IBAction, just read segmentControl.selectedSegmentIndex directly in IBAction of the Continue button.
I understand your question and had the same problem myself.
I experimented as I did not want any Segment in my Segmented Control to be highlighted or selected at all as this would cause confusion to my users and if the highlighted start index was actually what the User required,then when pressed did not perform the Action within the Switch Case area.
So... I made the Index Value -1 and this does not highlight any part of the Segment at all, it works a treat for my requirements and makes the user select the desired segment.
I set this up within my ViewDidLoad()
mySegmentedControlOutlet.selectedSegmentIndex = -1

Crash while reloading row and the whole table at the same time

I have a nice bug here, specially in slow devices.
I have a UITableView jusk like the ones in the App Store app, with a Load More button at the bottom.
When it is pressed, I load the new info from the server, set the array, and reload the table view. In that info is also the url of the image for each object displayed in the table rows, so when we got it we start donwloading the image. When the image is loaded, I reload the row of the object.
[self.searchResultsTableView reloadRowsAtIndexPaths: [NSArray arrayWithObject: path] withRowAnimation: UITableViewRowAnimationNone];
The problem comes when the row is being reloading because the image was downloaded, and the whole table is doing so cause the user pressed the load more button and more info was gotten. Then I get this error:
Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (140) must be equal to the number of rows contained in that section before the update (125), plus or minus the number of rows inserted or deleted from that section (1 inserted, 1 deleted).
Which is perfectly understable, the table was enlarged while the new image row was being updated.
My question is: how can lock it so I do not reload that row until the whole table is reloaded? It would nice something like table.isReloading. I try with a boolean lock, and doing both actions in the main thread, but it did not work ...
Thanks a lot.
Well, a little research in the doc put some more light in all this.
reloadRowsAtIndexPaths:withRowAnimation: Call this method if you want to alert the user that the value of a cell is changing. If, however, notifying the user is not important—that is, you just want to change the value that a cell is displaying—you can get the cell for a particular row and set its new value.
And that is what I did, I got the cell and set the new value for image, instead of reloading the whole of it. I guess it is more efficient also:
AHMyTableViewCell *cell = (AHMyTableViewCell *) [self.myTableView cellForRowAtIndexPath:path];
if ((cell != nil) && ([cell isKindOfClass:[AHMyTableViewCell class]]))
cell.myImageView.image = image;
It does not crash now.

set the page size with UITableView and paging.enabled=YES (or other way ?)

I'm struggling with this problem, although I'm close to the solution, but I guessing I'm missing something.
Here is the situation :
I have UITableView with 30 cells, and one section header (if it's helpful..).
The table size is exactly the size of 3 rows.
The mission : to let the user scroll 3 rows everytime, exactly 3.
I set the pagingEnabled=YES.
What happens is :
"page 1" - 3 rows - ok (rows 0-2)
swiping to "page 2" - next 3 rows - ok (row 3-5)
swiping to "page 3" - and the paging is not good, either skiping row 6 and showing row 7-9
or the page is stopped in the middle of the cell of 6 (also tried to move the scroll to complete cell visibilty with scolling end event, but it skips some of the rows on some pages)
Any ideas how to fix the situation, every page = 3 rows only ,without skipping or showing half of cell ?
I don't mind if the way will be without pagingEnabled=YES.
I arrived at the conclusion this is basic thing I will use in the future , and I think a lot of others will use the solution that other friends will give here.
Thanks.
Never thought of using this property in a Table View.
Since it is a subclass of UIScrollView, try instead to use the UIScrollViewDelegate methods and calculate where to stop.
A good place to start can be in scrollViewWillEndDragging:withVelocity:targetContentOffset:. and return the offset yourself.
P.S.
from the documentation:
This method is not called when the value of the scroll view’s
pagingEnabled property is YES. Your application can change the value
of the targetContentOffset parameter to adjust where the scrollview
finishes its scrolling animation.

Erratic UIPageControls

I'm using two UIPageControls in a view to reflect chapters and pages. So I have defined one UIPageControl named chapterCount and one named pageCount just to show where the user is. I handle the flipping of the pages with swipes rather than using the UIPageControls (so no methods defined for them).
I change their values as the user change pages with the following code:
chapterCount.numberOfPages = chapters;
chapterCount.currentPage = chapterNumber;
pageCount.numberOfPages = pages;
pageCount.currentPage = pageNumber;
[chapterCount updateCurrentPageDisplay];
[pageCount updateCurrentPageDisplay];
Where chapters, chapterNumber, pages and pageNumber all are integers.
The first time I flip through the pages it normally works fine, but when I go to a previous chapter or start a new chapter, the first (or last depending on direction) dot is not showed. Please see picture (upper half is missing a dot, lower one OK).
alt text http://img80.imageshack.us/img80/3339/pagecontrol.png
Its the same code updating the controls and sometime I get a dot, sometimes not. When I check the variables with NSLOG they are correct (eg the same for both pictures above).
I have checked Apple's documentation and tried their example but no luck.
Where should I start troubleshooting? I'm getting crazy!!
I finally found the problem :-)
An UIPageControl that is given a value 0 for number of pages will not show correctly the next time it is updated. I was reading chapter and page numbers from an array and in the beginning (let's say cover of the book) there are no pages and no chapters to show, so I happily set these to 0. Since I did not want to change the source data in my array I used MAX(pages , 1) for numberOfPages, so now it's working like clockwork.
Are you sure your chapterCount and pageCount views are not nil? You can have valid values all day, a message to nil does nothing and returns nil. Double check your view and controller wiring/unwiring when you change chapters.
EDIT:
confirm the size of the control is big enough to hold all your pages, and the view bounds is not clipped. For example, if you had 10 pages, and the "current" page was 10, but there were only 9 dots visible, it would appear as though nothing is highlighted because the white dot would be clipped from the visible area by being outside the viewable bounds. You can adjust the size dynamically using this:
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount

UITableView: moving a row into an empty section

I have a UITableView with some empty sections. I'd like the user to be able to move a row into them using the standard edit mode controls. The only way I can do it so far is to have a dummy row in my "empty" sections and try to hide it by using tableView:heightForRowAtIndexPath: to give the dummy row a height of zero. This seems to leave it as a 1-pixel row. I can probably hide this by making a special type of cell that's just filled with [UIColor groupTableViewBackgroundColor], but is there a better way?
This is all in the grouped mode of UITableView.
UPDATE: Looks like moving rows into empty sections is possible without any tricks, but the "sensitivity" is bad enough that you DO need tricks in order to make it usable for general users (who won't be patient enough to slowly hover the row around the empty section until things click).
I found that in iOS 4.3, the dummy row needs to have a height of at least 1 pixel in order to give the desired effect of allowing a row to be moved into that section.
I also found that the dummy row is only needed in the first and last section; any sections in between don't have this problem.
And it looks like in iOS 5.0, no dummy rows or special tricks are needed at all.
While managing the edit, you can monitor if the table view is in Edit Mode. Use that flag inside of cellForRowAtIndexPath to decide weather or not to display the 'blank' row. While in 'regular' mode, the row will not display, but when the user taps 'edit' cellForRowAtIndexPath should get called again and this time decide to display the row. The details of how to do that depend on your data source and how you are gluing it to the display. If you aren't getting the call again, you can manually inject rows with insertRowsAtIndexPaths / deleteRowsAtIndexPaths and/or call reloadData to force a refresh.
I found that if you return -1.0 from the heightForRowAtIndexPath method it will remove the 1 pixel line.