How to Access `UItextView` data from another view controller - objective-c

How I access the body of UITextView from another view controller for email here is my code
EmergencyMessageController *ViewB1 = [[EmergencyMessageController
alloc]initWithNibName:#"EmergencyMessageController" bundle:nil];
NSString *Em1 = ViewB1.Emsg.text;
NSString *body = [[NSString alloc] initWithFormat:#" ",Em1];//my problem is here to access Em1 data
controller.mailComposeDelegate = self;
[controller setSubject:#"Emergency Message"];
[controller setMessageBody:body isHTML:YES];
[controller setToRecipients:recipients];
[self presentModalViewController:controller animated:NO];

As you are creating another instance of "EmergencyMessageController" viewcontroller here, it won't give you any values.
You have to use the same instance variable using which you have set the email body in EmergencyMessageController.
or else as Vertogo said, this EmergencyMessageController should be the parent of this second view controller, so that you can easily access parent view controllers properties.

Hey user2396021 this is a simple example of Parent-Child View Controller,hope this will help you.
ParentViewController.h
Declare your textView as a class variable in parent view controller as below.
#import <UIKit/UIKit.h>
#interface ParentViewController : UIViewController
#property (nonatomic,strong) UITextView *mytextView;
#end
ParentViewController.m
Add textview to parentView Controller as below
- (void)viewDidLoad
{
[super viewDidLoad];
_mytextView = [[UITextView alloc]initWithFrame:CGRectMake(100, 100, 200, 30)];
[_mytextView setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:_mytextView];
}
ChildViewController.h
Make ParentViewController as a superclass(or you can say parentclass) of ChildViewController as below
#import "ParentViewController.h"
#interface ChildViewController : ParentViewController
#end
ChildViewController.m
Now you can easily access any class variable of parent class(ParentViewController) using "super" keyword.
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Text value of uitextview from Parent class %#",[[super mytextView]text]);
}

Related

Search Template tvOS

Anybody know how to implement search template like in Apple tvOS Human Interface Guidelines, using native development in Objective-C or Swift, without TVML ?
So, after research I was able to find a solution:
Objective - C
If in application is tabBar, i created a subclass from UITabBarController e.g. APTabBarController. In APTabBarController, in method
- (void)viewDidLoad
I do next:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SearchResultsViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:#"SearchResultsViewController"];
UISearchController *searchController = [[UISearchController alloc] initWithViewController:myViewController];
UISearchContainerViewController *containerVC = [[UISearchContainerViewController alloc] initWithSearchController: searchController];
containerVC.title = #"Search";
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController: containerVC];
NSMutableArray *newTab = [self.viewControllers mutableCopy];
[newTab addObject: navigationController];
[self setViewControllers: newTab];
Where:
storyboard - is my storyboard
SearchResultsViewController - is my controller from storyboard that contains collectionView
UISearchController - is controller that allow to find what do you need
UISearchContainerViewController - and these one is like a view controller from tabBarController
In "newTab" - I add fresh created viewController that i need
But, problem that I found is that i can't catch searched text. For that, create a subclass from UISearchController, and implement custom
initWithViewController
In my case it looks like these:
In .h
#import <UIKit/UIKit.h>
#interface SearchExercisesViewController : UISearchController
- (id) initWithViewController:(UIViewController *) viewController;
#end
In .m
#import "SearchExercisesViewController.h"
#interface SearchExercisesViewController () <UISearchBarDelegate>
#property (nonatomic, strong) UIViewController *viewController;
#end
#implementation SearchExercisesViewController
- (id) initWithViewController:(UIViewController *) viewController {
self = [super initWithSearchResultsController:viewController];
if (self) {
self.viewController = viewController;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.searchBar.delegate = self;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"%#",searchText);
}
#end
Profit, and now, replace
UISearchController *searchController = [[UISearchController alloc] initWithViewController:myViewController];
with
SearchExercisesViewController *searchController = [[SearchExercisesViewController alloc] initWithViewController:myViewController];
All done. Now only that remain is to sent data to viewController that contains collection view, and implement logic for search. For sent data you can you Delegate pattern or NSNotification. You can find how to implement that in that post:
it possible to Pass Data with popViewControllerAnimated?
Swift
In swift is the same, how to do that, you can find on Apple example from these link:
https://github.com/brunogb/TVExamples/tree/master/UIKitCatalogtvOSCreatingandCustomizingUIKitControls
Sounds like you want to look at UISearchController.

TextFields and text areas become unresponsive after performing validation in the textfield

I am creating a view controller in which UITextField are getting created dynamically.
self.ansText = [[UITextField alloc] init];
self.ansText.tag = 1;
self.ansText.delegate = self;
[_ansText createAnsTextwithParentFrame:QuestionView.frame withUpperFrame:questSeq2Frame];
[QuestionView addSubview:_ansText];
Here when I do a validation on the UITextField, text fields even in other view controllers become unresponsive.Here it is reaching UITextField ShouldBeginEditing method.I have gone through a number of similar question in stack overflow.And I saw a solution like setting the delegate not to self. But Could anyone please help me on this..Could you please elaborate on this. Thank you very much in advance.
#iOSManiac, delegate can be the UITextField, it's just
self.ansText.delegate = ansText;
Here's a more detailed answer, your And Text must be inherited from UITextField and it must implement UITextFieldDelegate
#interface ViewController ()
#end
#interface AnsText : UITextField <UITextFieldDelegate>
#end
#implementation AnsText
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
NSLog(#"textFieldShouldBeginEditing");
return YES;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AnsText *ansText = [[AnsText alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
ansText.tag = 1;
ansText.delegate = ansText;
[self.view addSubview:ansText];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

UIViewController Retaining in ARC

I have a subclass of UIViewController -> MyPopUpViewController
#protocol MyPopUpViewController Delegate;
#interface MyPopUpViewController : UIViewController
{
}
#property (nonatomic, strong) id <MyPopUpViewControllerDelegate> delegate;
-(IBAction) buttonPressed:(id)sender;
#end
#protocol MyPopUpViewControllerDelegate
-(void) popupButtonPressed: (MyPopUpViewController*)controller;
#end
I cannot have this MyPopUpViewController as an instance variable because this comes externally, and there could be many and multiple of these popups can be up. So far I tried this, and it crashes on the delegate call due to not being retained:
MyMainViewController:
-(void)externalNotificationReceived: (NSString*) sentMessage
{
MyPopUpViewController *popupView = [[MyPopUpViewController alloc] init];
popupView.delegate = self;
[self.view addSubview:popupView.view];
[popupView setInfo :sentMessage :#"View" :#"Okay"];
popupView.view.frame = CGRectMake(0, -568, 320, 568);
popupView.view.center = self.view.center;
}
-(void)popupButtonPressed:(MyPopUpViewController *)controller :(int)sentButtonNumber
{
NSLog(#"Popup Delegate Called");
[controller.view removeFromSuperview];
controller.delegate = nil;
controller = nil;
}
Once the popup comes up, and when the ok button is tapped, it crashes and never gets to that NSLog. How can I change
MyPopUpViewController *popupView = [[MyPopUpViewController alloc] init];
..so it would retain without making it an instance variable?
Thanks in advance.
You should be doing proper view controller containment by calling addChildViewController:.
- (void)externalNotificationReceived: (NSString*) sentMessage {
MyPopUpViewController *popupView = [[MyPopUpViewController alloc] init];
popupView.delegate = self;
[popupView setInfo :sentMessage :#"View" :#"Okay"];
popupView.view.frame = CGRectMake(0, -568, 320, 568);
popupView.view.center = self.view.center;
[self addChildViewController:popupView];
[self.view addSubview:popupView.view];
[popupView didMoveToParentViewController:self];
}
This will keep a proper reference to the view controller as well as properly pass various view controller events. Read about this in the docs for UIViewController and the "View Controller Programming Guide for iOS".
BTW - you should name your methods better. Example:
popupButtonPressed::
should be named:
popupButtonPressed:buttonNumber:
Usually delegates are weak-referenced instead of strong. I, myself, would name it something else as to not confuse other people.
Also, the following bit of code will have no effect:
-(void)popupButtonPressed:(MyPopUpViewController *)controller :(int)sentButtonNumber
{
...
controller = nil;
}
the controller would be released (set to nil) automatically at the end of the scope.

Add and control UIImageView Subview from another class

I have two classes: MainViewController and PlayerImageController (NSObject)
How would I be able to add the subview of my UIImageView from PlayerImageController to my MainViewController and dictate actions like
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:[PlayerImageController addPlayerImage]];
}
- (void)somethingHappened
{
[PlayerImageController changePlayerImage];
}
and have my methods in my PlayerImageController class like
+ (UIImageView *) addPlayerImage
{
heroPlayerImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"hero-still.png"]];
[heroPlayerImageView setFrame:CGRectMake(151, 200, 17, 23)];
return heroPlayerImageView;
}
+ (void) changePlayerImage
{
//change image
}
Thanks!
I think in your case you should use the Delegate pattern.
Declare:
#protocol PlayerImageUpdater
- createPlayerImage;
- changePlayerImage;
#end
Then add:
#interface PlayerImageController <PlayerImageUpdater>
then add to MainViewController ivar and property like:
#property (...) id<PlayerImageUpdater> playerDelegate;
set this delegate like: mainViewController.playerDelegate = playerImageControllerInstance;
and use in code:
[playerDelegate createPlayerImage];
[playerDelegate changePlayerImage];
On one hand, I would not recommend using class methods but instance methods. This way, you could implement as many instances of your class as you need and keep a reference to your instances to update them.
On the other hand, if the UIImageView is the important attribute of your class, I suggest you implement it as a UIView subclass (if it is not, you can do it as an NSObject subclass as well, and get its UIImageView attribute).
Have a look at the following code:
PlayerImageController.h:
#interface PlayerImageController : UIView{
UIImageView *_heroPlayerImageView;
}
-(void) changePlayerImage;
PlayerImageController.m:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_heroPlayerImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"hero-still.png"]];
// x = 0 and y = 0 because its relative to its parent view, the object itself.
[_heroPlayerImageView setFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
[self addSubview:_heroPlayerImageView];
}
return self;
}
MainViewController.h:
#import "PlayerImageController.h"
#interface MainViewController : UIViewController{
PlayerImageController *_player;
}
MainViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
_player = [[PlayerImageController alloc] initWithFrame:CGRect(151, 200, 17, 23)];
[self.view addSubview:_player];
}
- (void)somethingHappened
{
[_player changePlayerImage];
}
I hope it can help you (I haven't actually tried the code above, it could have some syntax errors).
If you are not using ARC, remember to retain and release your variables! Good luck!

Calling SEL from parentViewController in iOS

I have a ViewController in which I create a Modal ViewController. I have a SEL value in my modal that I set when it is being instantiated from the parent.
setDateViewController.selectorName = #selector(myMethod:);
In my modal I am trying to call this SEL like:
[[self parentViewController] performSelector:self.selectorName withObject:selectedDate afterDelay:.5];
{selectedDate} is obviously a value from my modal.
I don't get any errors or stack, however, this SEL (method) on my parent is never being called. For some reason I think this should work, but something tells me I'm way off track.
Thanks.
I guess [self parentviewcontroller] is not returning anything.
Try UiviewController* v = [self parentviewcontroller]; and check if is nil. Most probably it should be nil. Else if its was pointing to another object of different class then it would have crashed. Please do one thing. YOu should set bot the object and the methd you need to call. IT will solve any issues if it has any.
setDateViewController.selectorDelegate = self;
setDateViewController.selectorName = #selector(myMethod:);
call like this from parent class. So you can dynamically specify the method and the object you want to call gives more flexibility.
and use,
[selectorDelegate performSelector:self.selectorName withObject:selectedDate afterDelay:.5];
this should solve any issues.
Perhaps you would consider added a delegate protocol to your modal that will allow it to call the method on the parent.
Quick (untested) example:
// MyController.h
#protocol MyControllerDelegate;
#interface MyController : UIViewController
{
id<MyControllerDelegate> delegate;
}
#end
#protocol MyControllerDelegate <NSObject>
- (void)methodToCall:(id)sender;
#end
// MyControler.m
#implementation MyController
- (void) loadView
{
[super loadView];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(20.0f, 20.0f, 50.0f, 30.0f);
[btn setTitle:#"blah" forState:UIControlStateNormal];
[btn addTarget:self.delegate
action:#selector(methodToCall:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
#end
// ParentController.h
#interface ParentController : UIViewController<MyControllerDelegate>
{
}
#end
// ParentController.m
#implementation ParentController
- (void)methodToCall:(id)sender
{
NSLog(#"HERE");
}
#end
Just make sure when you are creating your modal controller you set it's delegate to self on the parent:
MyController *controller = [[MyController alloc] init];
controller.delegate = self;
[self presentModalViewController:controller animated:YES];