Hide Copy and Deselect UITextView options after copying all text - cocoa-touch

I am working on a messaging app. I want to give a "copy" option to the user when they enter their message in a UITextView. When the user presses the "copy" button, it is copying the message, but the popover shows again and again, and the text is still selectable.
I don't know how to control this. I have pasted some source code for your reference.
I wrote a sub class for UITextView.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
NSLog(#"Action : %#", NSStringFromSelector(action));
NSLog(#"Sender : %#", sender);
if (action == #selector(copy:))
{
[self selectAll:self];
//return [super canPerformAction:action withSender:sender];
return YES;
}
else if (action == #selector(cut:))
{
return NO;
}
return NO;
}

I have solved my problem. I have used below codes to solve.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == #selector(copy:))
{
[self selectAll:self];
return YES;
}
else if (action == #selector(cut:))
{
return NO;
}
return NO;
}
- (void)copy:(id)sender
{
UIPasteboard *pastBoard = [UIPasteboard generalPasteboard];
[pastBoard setString:self.text];
self.selectedTextRange = nil;
[self resignFirstResponder];
}
Thanks to Mr.Vimal Venugopalan and Mr.Mrueg. It is working for me. It will help to some one.

If you are using the iOS5
UITextView adopts the UITextInput protocol, which has a selectedTextRange property. Set the property to nil:
Add the below code just above the last return NO.
self.selectedTextRange = nil;
Hope this helps

Related

How do I switch views after signing up and logging in?

So the backend is working, I can successfully create accounts and login. Now I want them to transition to the home screen so how I do I set so if the sigup/login is successful it transitions? This is my code:
- (IBAction)signUp:(UIButton *)sender {
NSString *name = _textUsername.text;
NSString *password = _textPassword.text;
NSString *email = [_textEmail.text lowercaseString];
//---------------------------------------------------------------------------------------------------------------------------------------------
if ([name length] == 0) { [ProgressHUD showError:#"Name must be set."]; return; }
if ([password length] == 0) { [ProgressHUD showError:#"Password must be set."]; return; }
if ([email length] == 0) { [ProgressHUD showError:#"Email must be set."]; return; }
//---------------------------------------------------------------------------------------------------------------------------------------------
[ProgressHUD show:#"Please wait..." Interaction:NO];
PFUser *user = [PFUser user];
user.username = name;
user.password = password;
user.email = email;
user[PF_USER_EMAILCOPY] = email;
user[PF_USER_FULLNAME] = name;
user[PF_USER_FULLNAME_LOWER] = [name lowercaseString];
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (error == nil)
{
ParsePushUserAssign();
[ProgressHUD showSuccess:#"Succeed."];
[self dismissViewControllerAnimated:YES completion:nil];
}
else [ProgressHUD showError:error.userInfo[#"error"]];
}];
Also any idea why my text field doesn't automatically go to the next one? Pretty sure the code is right. Thanks.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == _textUsername)
{
[textField resignFirstResponder];
[_textEmail becomeFirstResponder];
}
else if (textField == _textEmail)
{
[textField resignFirstResponder];
[_textPassword becomeFirstResponder];
}
else if (textField == _textPassword)
{
[textField becomeFirstResponder];
[_textBirthday becomeFirstResponder];
}
else if (textField == _textBirthday)
{
[self actionRegister];
}
return YES;
The way I arrange my parse.com apps is to have the main VC, the one that does the app's usual business for a logged-in user, be the storyboard's starting VC. It's first job in viewDidAppear, is to check that the PFUser currentUser exists (and is logged-in if your app requires it). If it isn't, then and only then, present the login/signup VC.
When login/signup dismisses as you have it in the posted code, viewWillAppear in your main VC fires again and detects the ready-to-run condition. It's action in that case is to carry on with initialization for a logged in user.
EDIT - For example, I have an app where the main VC is the starting VC in storyboard. It has a segue with identifier == #"GetUser" drawn from it to my equivalent of your signup/login VC.
Here's the (slightly simplified) viewDidAppear from my main VC.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// I require only a non-nil currentUser to run the app. Your check
// might be more elaborate...
PFUser *user = [PFUser currentUser];
if (user) {
// put up a "busy" UI. In my app, it's just a view with UIActivityIndicator
// update the user so we know its current
[user fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) {
// remove the "busy" UI
[self startTheApp];
}];
} else {
[self performSegueWithIdentifier:#"GetUser" sender:self];
}
}
-(void)startTheApp {
// fetch data from parse.com and reload the table view that's the
// centerpiece of the UI for this VC.
}
The nice behavior here is when the login/signup succeeds, the currentUser is non-nil, so when the login/signup VC is dismissed, viewDidAppear as shown above is fired again because the main VC underneath is being revealed again. And on that second time through, the currentUser passes the starting condition and we go to startTheApp.

Custom InputView for UISearchBar doesn't work after tap cancel button in iOS7

In my iOS App , i need to set custom inputView for UISearchBar in iOS7.
So i wrote following codes.
NSArray *searchBarSubViews = [[self.sBar.subviews objectAtIndex:0] subviews];
for(int i =0; i<[searchBarSubViews count]; i++) {
if([[searchBarSubViews objectAtIndex:i] isKindOfClass:[UITextField class]])
{
UITextField* search=(UITextField*)[searchBarSubViews objectAtIndex:i];
[search setFont:[UIFont fontWithName:#"CustomFont" size:15]];
search.delegate = self;
[search setInputView:self.customKeyboard];
[self.customKeyboard setTextView:search];
}
}
It is working fine. However when i type with my custom keyboard and tap Cancel Button to resignFirstResponder.
And i tap UISearchBar again, i can't type any text in UISearchBar , including native english keyboard.
And also Cancel Button is hiding and UISearchBar is not working anymore.
I don't know why is happening?
How can i solve it?
I tried your code and it's working fine with my app. In fact thanks and congratulations seem to be in order, because for one reason or other you seem to have solved a problem others on this site had to built more elaborate workarounds for.
In my app the keyboard changes according to the selected scope of the searchbar:
scope == 0 presents my CustomKeyboard
scope != 0 presents the usual iPhone Keyboard.
My implementation of your code looks like this:
-(UITextField *)textFieldFormSearchBar{
NSArray *searchBarSubViews = [[self.searchBar.subviews objectAtIndex:0] subviews];
for(int i =0; i<[searchBarSubViews count]; i++) {
if([[searchBarSubViews objectAtIndex:i] isKindOfClass:[UITextField class]])
{
UITextField* search=(UITextField*)[searchBarSubViews objectAtIndex:i];
return search;
}
}
return nil;
}
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{
if (searchBar.selectedScopeButtonIndex==0) {
self.textFieldFormSearchBar.delegate = self;
self.textFieldFormSearchBar.inputView=self.customKeyboard;
self.customKeyboard.field=self.textFieldFormSearchBar;
}
else{
if (self.customKeyboard.superview!=nil) [self.customKeyboard removeFromSuperview];
self.textFieldFormSearchBar.delegate = self;
self.textFieldFormSearchBar.inputView=nil;
self.customKeyboard.field=nil;
}
return YES;
}
-(void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope{
if (selectedScope==0) {
self.textFieldFormSearchBar.delegate = self;
self.textFieldFormSearchBar.inputView=self.customKeyboard;
self.customKeyboard.field=self.textFieldFormSearchBar;
}
else{
if (self.customKeyboard.superview!=nil) [self.customKeyboard removeFromSuperview];
self.textFieldFormSearchBar.delegate = self;
self.textFieldFormSearchBar.inputView=nil;
self.customKeyboard.field=nil;
}
[self.textFieldFormSearchBar reloadInputViews];
}
-(BOOL)searchBarShouldEndEditing:(HDLSearchBar *)searchBar{
if (self.customKeyboard) {
[self.customKeyboard removeFromSuperview];
}
return [self.textFieldFormSearchBar resignFirstResponder];
}
Probably not the most efficient way to do it, but it does the trick. I hope you'll find something that helps you solve your problem.

Objective-C: Why is my if statement not working?

Here i have some code that checks if the iphone has a camera flash. And then check if my switch is on by using this code:
if(switch1.on){
}
The light turns on fine without this code and i have also tried this code as well:
if(!(switch1.on)){
}
and that successfully turns my camera flash on but also turns it on even when the switch is set to off
Here is my full code:
-(IBAction)torchon:(id)sender{
AVCaptureDevice *flashlight = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([flashlight isTorchAvailable] & [flashlight isTorchModeSupported:AVCaptureTorchModeOn]) {
BOOL success = [flashlight lockForConfiguration:Nil];
if(success){
if(switch1.on){ //// or (!(switch1.on))
on.hidden = YES;
[UIScreen mainScreen].brightness = 1.0;
[flashlight setTorchMode:AVCaptureTorchModeOn];
[flashlight unlockForConfiguration];
}
}
}
}
any help would be appreciated
**EDIT:**
Here is the code where i set the switch to no using ibactions when the value of the switch has changed. This code works successfully:
-(IBAction)switch1{
if (switch1.on) {
switch1.on = YES;
switch2.on = NO;
} else{
switch2.on = YES;
switch1.on = NO;
}
}
-(IBAction)switch2{
if (switch2.on) {
switch2.on = YES;
switch1.on = NO;
} else{
switch1.on = YES;
switch2.on = NO;
}
}
Answer
First add a bool:
bool yes;
then set that bool in the viewdidload
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
yes = YES;
}
After that set it to YES when the ibaction is called and set it to NO once the switch is turned off:
-(IBAction)switch1{
if (swich1.on) {
swich1.on = YES;
swich2.on = NO;
yes = YES;
}
}
-(IBAction)switch2{
if (swich2.on) {
swich2.on = YES;
swich1.on = NO;
yes = NO;
}
}
lastly where it checks if(switch1.on){} you need to change it to if(yes==YES){} so together that if statement looks like this:
-(IBAction)torchon:(id)sender{
AVCaptureDevice *flashlight = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([flashlight isTorchAvailable] & [flashlight isTorchModeSupported:AVCaptureTorchModeOn]) {
BOOL success = [flashlight lockForConfiguration:Nil];
if(success){
if(yes==YES){
on.hidden = YES;
[UIScreen mainScreen].brightness = 1.0;
[flashlight setTorchMode:AVCaptureTorchModeOn];
[flashlight unlockForConfiguration];
}
}
}
}
The UISwitch has another getter for the on property.
#property(nonatomic, getter=isOn) BOOL on;
It may be better to use .isOn instead of .on for getting the value.
Also, some of your code can be simplified:
-(IBAction)switch1{
[switch2 setOn:!switch1.isOn];
}
-(IBAction)switch2{
[switch1 setOn:!switch2.isOn];
}
It can get even better if you use the sender of the action in your methods.
It seems that your IBAction methods have a similar form as the getter for the switch. It is possible that this could lead to undesired side effects. Refactor your methods to a single method, more in line with good programming practice:
-(IBAction)switchDidChange:(UISwitch*)aSwitch {
UISwitch* otherSwitch = (aSwitch == switch1)? switch2 : switch1;
[otherSwitch setOn:!aSwitch.on animated:YES];
}
Also, in your code the on property does not really seem to influence what is switched on or off. Include this conditionality.

Call a method from within a sibling method with parameters

I have followed the first steps tutorial from apple, and I have a working app that can read text and display it in a label on button click. When I hit enter the textfield is resigned and the keyboard disappears, and when I hit the button the changeGreeting method is invoked. I want to call the changeGreeting function in the function thats used when I hit enter which is textFieldShouldReturn.
I tried everything I could think of, and read a lot online but Im not sure how to deal with (id)sender as a param for example. How should I edit my code to call changeGreeting on textfield enter?
code below:
- (IBAction)changeGreeting:(id)sender {
self.userName = self.textField.text;
NSString *nameString = self.userName;
NSString *endString = #"burp";
int r = arc4random() % 74;
if ([nameString length] == 0) {
nameString = #"World";
}
NSString *greeting = [[NSString alloc] initWithFormat:#"Hello, %#, %#! Random String of numbers: %d", nameString, endString, r];
self.label.text = greeting;
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.textField) {
[theTextField resignFirstResponder];
// on enter the keyboard is removed, but I want the
// changeGreeting method involed too, something like
// [self changeGreeting]
}
return YES;
}
thanks in adv
You already have it. Just ignore the sender parameter:
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.textField) {
[theTextField resignFirstResponder];
// on enter the keyboard is removed, but I want the
// changeGreeting method involed too, something like
[self changeGreeting:nil]
}

UIPickerView inside UIScrollView hitTest to disable Scrollview?

I am currently building an application which has a resized UIPickerView on a scrollview the problem I am facing is that when you try to scroll the picker the scrollview is moving instead.
For the past few hours I have tried to fix this by disabling the scrollview when the picker is selected by creating a UIScrollView sub class which performs the following hitTest:
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView* result = [super hitTest:point withEvent:event];
if ([result.superview isKindOfClass:[UIPickerView class]])
{
NSLog(#"Cancel touch");
self.canCancelContentTouches = NO;
self.delaysContentTouches = NO;
self.scrollEnabled = NO;
}
else
{
self.canCancelContentTouches = YES;
self.delaysContentTouches = YES;
self.scrollEnabled = YES;
}
return result;
}
With this above code I find that when I click and hold certain sections of the UIPickerView it cancels the touch and disables the UIScrollview OK and I can move the UIPicker to select a new value, however when I certain areas on the PickerView and do an NSLog on the reported class like below
NSLog(#"%#", [result.superview class]);
It outputs UIPickerTableViewWrapperCell to the console and the isKindOfClass[UIPickerView class] never gets entered.
I have also tried isMemberOfClass which also does not work.
Any help would be appreciated.
Thanks Aaron
I think I have figured this out, by searching the class description to see if it contains #"UIPicker*"
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView* result = [super hitTest:point withEvent:event];
NSString *viewDescription = [result.superview class].description;
NSRange range = [viewDescription rangeOfString : #"UIPicker"];
if (range.location != NSNotFound)
{
NSLog(#"Cancel touch on ScrollView");
self.canCancelContentTouches = NO;
self.delaysContentTouches = NO;
self.scrollEnabled = NO;
}
else
{
self.canCancelContentTouches = YES;
self.delaysContentTouches = YES;
self.scrollEnabled = YES;
}
return result;
}
Now when I drag the UIPicker it works perfectly and the scrollview does not move at all, unless I am clicking on that and dragging it.
Aaron