iOS: Switch UIViews using ReactiveCocoa - ios

I am having some trouble kicking-off with ReactiveCocoa
So basically - I have 2 (potentially N) UIButtons which when tapped on should trigger a different view to be displayed on the screen.
At the moment I am achieving it in the following way:
- (IBAction)firstButtonTapped:(id)sender {
[self processViewDisplayForViewType:ViewTypeFirstType];
}
- (IBAction)secondButtonTapped:(id)sender {
[self processViewDisplayForViewType:ViewTypeSecondType];
}
-(void)processViewDisplayForViewType:(ViewType)viewType{
switch (viewType) {
case ViewTypeFirstType:
//process showing a view based on the given type
break;
case ViewTypeSecondType:
//process showing a view based on the given type
break;
default:
break;
}
self.currentViewType = viewType;
}
Now, if I have other display types I would need to add aditional statements in the switch block... so I hope I can solve this using ReactiveCocoa and FRP. Anybody can point me in the right direction on solving this ?

Related

Core-Plot: maintain zoomed-in range on reloadData

My CPTScatterPlot allows pinching to zoom-in to see more detailed data, as well as some parameters that can be changed. Whenever the parameters are changed, I recalculate the data points, followed by reloadData. However, that again shows the whole data range, instead of keeping the zoomed-in range.
EDIT: What I have tried so far:
-(CPTPlotRange *)plotSpace:(CPTPlotSpace *)space willChangePlotRangeTo:(CPTPlotRange *)newRange forCoordinate:(CPTCoordinate)coordinate
{
CPTPlotRange *updatedRange = nil;
switch ( coordinate )
{
case CPTCoordinateX:
if ([newRange isEqualToRange: ((CPTXYPlotSpace *)space).globalXRange]) {
updatedRange = ((CPTXYPlotSpace *)space).xRange;
}
else {
updatedRange = newRange;
}
break;
case CPTCoordinateY:
case CPTCoordinateZ:
case CPTCoordinateNone:
break;
}
return updatedRange;
}
I have a hunch I need to do this in this delegate method, but I have not yet been able to figure out how.
Is there a way to maintain the zoomed-in range whenever reloadData is called?
EDIT 2: Solved by adding a dataIsLoaded flag so that I only set xRange initially, but not on every re-calculation. The delegate method above is not related to the problem.

Identify which UISwitch is tapped

I have multiple UISwitches on settings view, and linked all UISwitches to same IBAction function.
#IBAction func settingSwitchTapped(sender: AnyObject) {
}
How do i find which UISwitch is tapped so that i just save only the switch that actually changed (instead of saving all others also)
That's the sole purpose of the sender parameter.
If all your switches are defined as IBOutlets, you can compare sender to each of them in order to know which one you've tapped.
You can also give each of them a different tag property, and decide what to do based on sender.tag.
Set tag for each Switch with a unique no.
you can get exact switch by using following :
switch = sender.tag
Hope it helps
#IBAction func settingSwitchTapped(sender: AnyObject) {
switch (sender.tag){
case 101: // your tag
// executable code goes here
break;
case 102: // your tag
break;
case 103: // your tag
break;
default:
break;
}
}

Touch event based on random number generated on object

int rand=((arc4random()%4)+1);
how would you go about making a touch event due to the numbers generated from int rand.
Example if the numbers generated are 1,2,2,3,4 and you have 4 buttons with a tag 1,2,3,4.
how would you make an event where you have to touch an object in order of the number generated by the int rand method?
Make 4 buttons give oneaction
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
rand=((arc4random()%4)+1);
}
-(IBAction)myMethod
{
switch (rand)
{
case 1:
//Do for first button tag
break;
case 2:
//Do for second button tag
break;
case 3:
//Do for third button tag
break;
case 4:
//Do for fourth button tag
break;
default:
break;
}
}

segmented control: titleForSegmentAtIndex returns null every time

I have a segmented control (Added via story board) and have set two segments (set in story board). When it is clicked it fires my 'segmentedIndexChanged:' method, but in that method i can't get the values (it always returns null) for either .selectedSegmentedIndex or titleForSegmentedAtIndex
-(IBAction) segmentedIndexChanged {
NSLog(#"index, text value: %# , %#", self.mySegControl.selectedSegmentIndex, [mySegControl titleForSegmentAtIndex:mySegControl.selectedSegmentIndex]
);
switch (self.mySegControl.selectedSegmentIndex) {
case 0:
NSLog(#"segmented 1 selected");
break;
case 1:
NSLog(#"segmented 2 selected");
break;
default:
break;
}
}
any ideas why?
Are you sure the outlet is connected to the control? You can check by printing out NSLog(#"%#", self.mySegControl)
Also, usually, IBActions should have the form of - (IBAction)action:(id)sender, that way you would be able to access the sender (in this case the segmented control) without having an outlet to it as well.

NSFetchedResultsChangeUpdate crashes when called on a searched tableview

So I nearly have this thing figured out, but I am stumbling over the NSFetchedResultsChangeUpdate when I update my managedObjectContext from a detail view that was entered after searching the table.
I have a tableview generated from a core data set. I can enter a detail view from this table and make changes without any issue. I can also search the table and make changes MOST of the time without any issues. However, on certain objects, I get an "Exception was caught during Core Data change processing".
I tracked this down to the NSFetchedResultsChangeUpdate. I'm using the following code:
case NSFetchedResultsChangeUpdate:
if (searchTermForSegue)
{
NSLog(#"index info:%#.....",theIndexPath);
NSLog(#"crashing at the next line");
[self fetchedResultsController:self.searchFetchedResultsController configureCell:[tableView cellForRowAtIndexPath:theIndexPath] atIndexPath:theIndexPath];
break;
} else {
[self fetchedResultsController:controller configureCell:[tableView cellForRowAtIndexPath:theIndexPath] atIndexPath:theIndexPath]; }
break;
When the table is not being searched, it runs the else method and that works 100% of the time. When the table is being searched, it runs the if (searchTermForSegue) and that works most of the time, but not always. I logged theIndexPath and discovered the following:
When it works, theIndexPath is correctly reporting the objects indexPat, when it fails, the wrong theIndexPath has been called. For example, if I do a search that narrows the tableView to 3 sections, 2 items in first, 1 in second, 1 in third, I get the following nslog:
On first object: index info:<NSIndexPath 0xb0634d0> 2 indexes [0, 0].....
on second object: index info:<NSIndexPath 0xb063e70> 2 indexes [0, 1].....
on third object: index info:<NSIndexPath 0xb042880> 2 indexes [1, 0].....
but on the last object: index info:<NSIndexPath 0x9665790> 2 indexes [2, 17].....
it should be calling [2, 0]
Note that I am simply updating these objects, not deleting them or adding new ones.
Any thoughts would be appreciated!
Okay, I have figured out a hack that seems to fix the issue, but it doesn't seem like the best way to solve the problem! Any thoughts?
I discovered when NSFetchedResultsChangeUpdate was called from a base table, it was only called once, but when it was called from a searched/filtered table it was called twice (seemingly 100% of the time - I suppose this is to refresh both the searched table and non-searched table?). In addition, the first call always seemed to have the incorrect indexPath while the second call had the correct information. The first call would crash the app if the incorrect indexPath was out of bounds.
My "fix" was to ignore the first call if NSFetchedResultsChangeUpdate from a searched table by doing the following
adding to the interface of the tableview.h file:
int changeCall;
then, in the tableview.m file, in loadView:
changeCall = 0;
Then I updated the NSFetchedResultsChangeUpdate to this:
case NSFetchedResultsChangeUpdate:
if (searchTermForSegue)
{
if (changeCall == 0) {
changeCall++;
break;
} else if (changeCall == 1){
NSLog(#"index infocalledtwice:%#.....",theIndexPath);
[self fetchedResultsController:self.searchFetchedResultsController configureCell:[tableView cellForRowAtIndexPath:theIndexPath] atIndexPath:theIndexPath];
changeCall = 0;
break;
} else { break; }
} else {
[self fetchedResultsController:controller configureCell:[tableView cellForRowAtIndexPath:theIndexPath] atIndexPath:theIndexPath];
}
break;
Essentially, using the changeCall int to skip the first call in a searched table update but use the second call to actually update the content. This CAN'T be the best way to fix this problem, but the bandaid seems to work. I would certainly appreciate if someone has a better answer.
In addition, by skipping the first NSFetchedResultsChangeUpdate, the non-searched table is not updated to reflect the new values. I've fixed this by adding a call to reload the table in the searchDisplayControllerWillEndSearch method:
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[self setSearchTermForSegue:nil];
[self.tableView reloadData];
}
Thanks!

Resources