Dynamically change UIActionSheet buttons and actions - objective-c

I have a UIActionSheet that I created Dynamically and it can have a number of buttons from 1 to 5 including cancel button. I can get the cancel button to work fine but lets say that only 2 buttons are need to be added onto the UIActionSheet, lets say they buttons 2 and 4 how do I determine which action to carry out. Cause normally I would use something like.
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch(buttonIndex) {
case 0:
// Do something here.
break;
case 1:
// Do something else here.
break;
case 2:
// Do something else again.
break;
case 3:
// Do something else here again.
break;
default:
break;
}
But if I only add two buttons dynamically there only going to use cases 0, 1. But if I add button 4 as one of the two buttons I still want it to use case 3. Is this possible or is there another way of doing it?

Use the buttonTitleAtIndex: method to check against the buttons' titles. You have to take care that your code won't break if you change a button's title in one place, though. It's probably best to save each button's title in an extra variable when you create the buttons and use this variable to compare with the button titles later.

When you create the UIActionSheet, keep a separate array mapping your button indexes to the actual tasks you want to perform (an actions enumeration, for example).
Then switch on tasks[buttonIndex] instead of buttonIndex.

Related

How can you reorder the way VoiceOver reads UIAccessibilityElements?

There are 2 answers on SO concerning this, but neither seem to work any longer.
I have a custom UITableViewCell. There are various labels laid out on this cell. VoiceOver for Accessibility reads things Left to Right, Top to Bottom.
This is an issue for the layout of my cell. I need things to be read in a specific order.
However, I don't seem to be able to change the order in which VoiceOver reads things by default.
I've tried self.accessibilityElements = #[self.view5, self.view1, self.view9] for example, but this does not change order.
You can set the cell's accessibility label with the string that you create combining all cell's subviews, for example if you have lbl1, lbl2, lbl3, btn1:
NSString *cellAccessibilityString = [NSString stringWithFormat:#"%#,%#,%#,%#", _lbl3.text, _lbl2.text, _btn1.text, _lbl1.text];
[self setAccessibilityLabel:cellAccessibilityString];
Where "self" is the cell.
No, Voice over doesnt work like that. You cannot change the order of the accessibility elements. YOu can only skip some elements which are in the stack.
Let's say you have views 1 to 9 in a vertical layout
and you do this:
self.accessibilityElements = #[self.view5, self.view1, self.view9]
IT doesnt mean that accessibility will read view 5 first, and then view 1 and then view 9.
YOu should give the order like:
self.accessibilityElements = #[self.view1, self.view5, self.view9]
So that the voice over only reads them in the order 1,5,9, and it skips the remianing!!!!
Again the voice over reads in the order left to right and from top to bottom!!!
Think it like this: USe self.accessibilityElements only if you want to add/skip the accessibility for the elements in your view, but not for the accessibility order!!!

How to detect if a button is in a desired area in Objective c

How can I detect if a button is in a desired area
I have used if( button.frame.orgin.x == area.framee.orgin.x){
if (button.frame.orgin.y == area.frame.orgin.y )};
The Problem with this code is that it is very exact so it is hard to match up the button with the label. So I would like to know how to detect if a button is inside a desired area. And how to make the area bigger than the button. Thanks In advance
Your best option is probably CGRectContainsRect() which would work something like:
if(CGRectContainsRect(someRect, button.frame))
{
//Button is in area.
}
To expand the rect you can use CGRectInset(), passing negative values to increase the frame size by that amount. This function will maintain the center of the original rect.
CGRect newRect = CGRectInset (smallRect, -10.0f, -10.0f);
You can read more about CGGeometry functions in the docs.
Use GCRectContainsRect(frame1, frame2); to see if an object is contained within another object. Or use CGRectIntersectsRect(frame1, frame2); to see if the rects overlap at all.

Limiting NSTableView to two selections

I am wondering if anyone has a method to limiting the number of selections allowed in an NSTableView to 2 concurrent selections. I am trying to calculate the delta between two selected values and would like for it to only select two at a time.
I was thinking of trying to keep track of what has been selected so that I can programmatically unselect anything if the selection expands above two, but this seems kludgy and possibly not as easy as it sounds.
Implement the delegate method tableView:shouldSelectRow: and return NO if you don't think the user should be allowed to select the row. For any reason you decide - for instance because the number of selected rows is already 2.
To get the number of currently selected rows at any given time, just call selectedRowIndexes on the table view (not the delegate, nor data source). This will give you an NSIndexSet, which has a count method with the information you are looking for.
The index set also holds the information about the other row indexes already selected, in case you want to deselect them.
Not knowing anything about the app, the user experience sounds a bit... strange. It is easy enough to implement, though, so no harm done in trying it out.
In your Table View's delegate you can implement -[<NSTableViewDelegate> tableViewSelectionDidChange:(NSNotification *)]
Maybe something like this:
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
switch ([notification.object numberOfSelectedRows]) {
case 0: break; // Nothing is selected
case 1: break; // Only one row selected
case 2: break; // Two rows
default:
... unselect rows ...
break;
}
}
Of course you can also use an if statement. Maybe you also want to store in which order the rows are clicked—this could be done in the cases one and two.
Thank you both for coming up with something to help jog my brain into the right direction. I started exploring the NSTableViewDelegate a little bit more hoping to find something to help with this and re-read this method: tableView:shouldSelectRow and it allows me to permit or reject the row selection. So now I can simply reject selecting a third row provided I have 2 already selected:
- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex
{
BOOL returnValue = YES;
if (_timeStampList.selectedRowIndexes.count >= 2)
returnValue = NO;
return returnValue;
}
I'll have to work on it some more to get exactly the behavior I want because with this small snippet it just rejects the user from selecting anything more; kind of abrupt about it too. So I'll probably add some more code to allow the user to select a new row while auto-un-selecting something else.
Thanks again!

Make the divider of an NSSplitView undraggable and don't show the dragging cursor

I have an NSSplitView (NO UISplitView(Controller)!!) with three subviews. Now, for the last divider (index 1), I want the divider to not show the dragging cursor (two arrows pointing out of eachother). I have this to stop the dragging, but the cursor is still showing up:
- (CGFloat)splitView:(NSSplitView *)splitView constrainSplitPosition:(CGFloat)proposedPosition ofSubviewAt:(NSInteger)dividerIndex {
if (dividerIndex == 1) {
return [splitView frame].size.width - 161;
}
}
Note that I only want to hide the cursor for the divider at index 1. Can anyone help me? Thanks. :)
No, I don't want to use BWToolkit.
I know this has been answered for a while, but the supplied answer did not suit my needs.
The delegate method splitView:effectiveRect:forDrawnRect:ofDividerAtIndex: allows you to set the effective rectangle for dragging the divider. If you return NSZeroRect no drag cursor will ever appear, regardless of your setup in splitView:constrainMaxCoordinate:ofSubviewAt: and splitView:constrainMinCoordinate:ofSubviewAt:.
Try using splitView:constrainMaxCoordinate:ofSubviewAt: and splitView:constrainMinCoordinate:ofSubviewAt: instead of splitView:constrainSplitPosition:ofSubviewAt:.
The former two methods are called once as the user drags the mouse and they give enough information for NSSplitView to know how to change the cursor during the drag.
The latter is called repeatedly as the user drags the splitter, so NSSplitView doesn't have enough information to know that you're returning a constant value each time and therefore can't change the cursor.

Application:openFiles: separate files by groups

I need that my application detect how many files has been dropped to it dock icon. For this i use application:openFiles: method
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
NSLog(#"%d",[filenames count]);
}
But unfortunately files sometimes separates by group. So, for example i dragged 3 files to dock icon and get this output:
2
1
How could it be?
Unfortunately that's life. If you really need to count the number of files received in a drop to the Dock icon, you need to set up a timer to combine the results received by the call application:openFiles: within a second (or some appropriate length of time.)