I need to draw a line between 2 points within a View component. Is this something I should learn React Native ART for? What would be the easiest way to accomplish this in React Native?
Thank you!
androiddrawiosreact-nativereactjs
I need to draw a line between 2 points within a View component. Is this something I should learn React Native ART for? What would be the easiest way to accomplish this in React Native?
Thank you!
Important: This check should always be performed asynchronously. The majority of answers below are synchronous so be careful otherwise you'll freeze up your app.
Install via CocoaPods or Carthage: https://github.com/ashleymills/Reachability.swift
Test reachability via closures
let reachability = Reachability()!
reachability.whenReachable = { reachability in
if reachability.connection == .wifi {
print("Reachable via WiFi")
} else {
print("Reachable via Cellular")
}
}
reachability.whenUnreachable = { _ in
print("Not reachable")
}
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
Add SystemConfiguration framework to the project but don't worry about including it anywhere
Add Tony Million's version of Reachability.h and Reachability.m to the project (found here: https://github.com/tonymillion/Reachability)
Update the interface section
#import "Reachability.h"
// Add this to the interface in the .m file of your view controller
@interface MyViewController ()
{
Reachability *internetReachableFoo;
}
@end
Then implement this method in the .m file of your view controller which you can call
// Checks if we have an internet connection or not
- (void)testInternetConnection
{
internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];
// Internet is reachable
internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Yayyy, we have the interwebs!");
});
};
// Internet is not reachable
internetReachableFoo.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Someone broke the internet :(");
});
};
[internetReachableFoo startNotifier];
}
Important Note: The Reachability class is one of the most used classes in projects so you might run into naming conflicts with other projects. If this happens, you'll have to rename one of the pairs of Reachability.h and Reachability.m files to something else to resolve the issue.
Note: The domain you use doesn't matter. It's just testing for a gateway to any domain.
This question seems to be very popular here on Stack Overflow so I thought I would try and give a better answer to help out people starting in the world of iOS like me.
I hope this answer is clear enough for people to understand and that I have not missed anything.
Passing Data Forward
Passing data forward to a view controller from another view controller. You would use this method if you wanted to pass an object/value from one view controller to another view controller that you may be pushing on to a navigation stack.
For this example, we will have ViewControllerA and ViewControllerB
To pass a BOOL value from ViewControllerA to ViewControllerB we would do the following.
in ViewControllerB.h create a property for the BOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
in ViewControllerA you need to tell it about ViewControllerB so use an
#import "ViewControllerB.h"
Then where you want to load the view, for example, didSelectRowAtIndex or some IBAction, you need to set the property in ViewControllerB before you push it onto the navigation stack.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.isSomethingEnabled = YES;
[self pushViewController:viewControllerB animated:YES];
This will set isSomethingEnabled in ViewControllerB to BOOL value YES.
Passing Data Forward using Segues
If you are using Storyboards you are most likely using segues and will need this procedure to pass data forward. This is similar to the above but instead of passing the data before you push the view controller, you use a method called
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
So to pass a BOOL from ViewControllerA to ViewControllerB we would do the following:
in ViewControllerB.h create a property for the BOOL
@property (nonatomic, assign) BOOL isSomethingEnabled;
in ViewControllerA you need to tell it about ViewControllerB, so use an
#import "ViewControllerB.h"
Create the segue from ViewControllerA to ViewControllerB on the storyboard and give it an identifier. In this example we'll call it "showDetailSegue"
Next, we need to add the method to ViewControllerA that is called when any segue is performed. Because of this we need to detect which segue was called and then do something. In our example, we will check for "showDetailSegue" and if that's performed, we will pass our BOOL value to ViewControllerB
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
controller.isSomethingEnabled = YES;
}
}
If you have your views embedded in a navigation controller, you need to change the method above slightly to the following
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showDetailSegue"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
controller.isSomethingEnabled = YES;
}
}
This will set isSomethingEnabled in ViewControllerB to BOOL value YES.
Passing Data Back
To pass data back from ViewControllerB to ViewControllerA you need to use Protocols and Delegates or Blocks, the latter can be used as a loosely coupled mechanism for callbacks.
To do this we will make ViewControllerA a delegate of ViewControllerB. This allows ViewControllerB to send a message back to ViewControllerA enabling us to send data back.
For ViewControllerA to be a delegate of ViewControllerB it must conform to ViewControllerB's protocol which we have to specify. This tells ViewControllerA which methods it must implement.
In ViewControllerB.h, below the #import, but above @interface you specify the protocol.
@class ViewControllerB;
@protocol ViewControllerBDelegate <NSObject>
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
@end
Next still in the ViewControllerB.h, you need to set up a delegate property and synthesize in ViewControllerB.m
@property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
In ViewControllerB we call a message on the delegate when we pop the view controller.
NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
[self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
That's it for ViewControllerB. Now in ViewControllerA.h, tell ViewControllerA to import ViewControllerB and conform to its protocol.
#import "ViewControllerB.h"
@interface ViewControllerA : UIViewController <ViewControllerBDelegate>
In ViewControllerA.m implement the following method from our protocol
- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
{
NSLog(@"This was returned from ViewControllerB %@", item);
}
Before pushing viewControllerB to navigation stack we need to tell ViewControllerB that ViewControllerA is its delegate, otherwise we will get an error.
ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
viewControllerB.delegate = self
[[self navigationController] pushViewController:viewControllerB animated:YES];
NSNotification center
It's another way to pass data.
// Add an observer in controller(s) where you want to receive data
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeepLinking:) name:@"handleDeepLinking" object:nil];
-(void) handleDeepLinking:(NSNotification *) notification {
id someObject = notification.object // Some custom object that was passed with notification fire.
}
// Post notification
id someObject;
[NSNotificationCenter.defaultCenter postNotificationName:@"handleDeepLinking" object:someObject];
Passing Data back from one class to another (A class can be any controller, Network/session manager, UIView subclass or any other class)
Blocks are anonymous functions.
This example passes data from Controller B to Controller A
Define a block
@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h
Add block handler (listener)
Where you need a value (for example, you need your API response in ControllerA or you need ContorllerB data on A)
// In ContollerA.m
- (void)viewDidLoad {
[super viewDidLoad];
__unsafe_unretained typeof(self) weakSelf = self;
self.selectedVoucherBlock = ^(NSString *voucher) {
weakSelf->someLabel.text = voucher;
};
}
Go to Controller B
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];
vc.sourceVC = self;
[self.navigationController pushViewController:vc animated:NO];
Fire block
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
NSString *voucher = vouchersArray[indexPath.row];
if (sourceVC.selectVoucherBlock) {
sourceVC.selectVoucherBlock(voucher);
}
[self.navigationController popToViewController:sourceVC animated:YES];
}
Best Solution
You can use the react-native SVG library.
https://github.com/react-native-community/react-native-svg#line