Change the minus image and action when UITableView is in edit mode - iphone

I have two questions:
Can we change the tap event of the (-) minus sign that appears when the table is in editmode?
Can we change the image of the minus sign that appears when the table is in edit mode?
I tried to find the solution in various posts but failed. So if you know the solution in any other post kindly paste the link over here.

You can't change the minus sign image, but if you are using it to actually delete items then I would recommend that you keep it as it is anyway. The reason is that it is a well-known icon to iPhone users. If you want to represent delete in some other way, it may be potentially confusing.
That said, if you want the left button to represent something else, then you can create a custom table cell with an image on the left. That image can be anything you want then. You can display or hide the custom icon by overriding didTransitionToState:

Quoting Chris Carrett
You can't change the minus sign image, but if you are using it to actually delete items then I would recommend that you keep it as it is anyway. The reason is that it is a well-known icon to iPhone users. If you want to represent delete in some other way, it may be potentially confusing.
However if you really want to change the icon you could try to remove it and add your own UIImageView in place.
Update:
I struggled with this but think I finally got it right.
I made a github repo as an example but this is the code hiding the old image:
- (void) removeOriginalEditControl{
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellEditControl"]) {
for (UIView *subsubview in subview.subviews) {
if ([NSStringFromClass([subsubview class]) isEqualToString:#"UIImageView"]) {
[subsubview removeFromSuperview];
break;
}
}
}
}
}
Check out the full example at: https://github.com/tiemevanveen/TableViewCustomEditControls

Related

Phonegap: completely removing the black bar from the iPhone keyboard

We're using Phonegap to develop our mobile app, and we borrowed code from here to remove the black next/prev/done bar from the keyboard:
https://stackoverflow.com/a/9276023/35364
What that code does is it finds the black bar, as a UIView object, and calls 'removeFromSuperview' on it.
We're not familiar with the iOS SDK/API. So while we can look at the code and get an idea of what it's doing, we can't tell if it's doing it properly, or how to improve it.
The specific problem we're running into:
We have a text field for writing a message, and we're manually controlling the placement of this field to be exactly above the keyboard, similar to the native sms app. In other words, we're putting it where the black bar was supposed to be.
When we focus/type in the message field, the system pushes the view up. It seems like this is a mechanism to make sure the text field is not invisible when the user types in it.
This is happening even though the text field is visible.
I noticed that by putting the input field right above where the black bar would normally be (as oppose to behind it), the view doesn't scroll.
So it seems the system somehow thinks the black bar is still there!
(To double check: when the black bar is not removed, and we put the text field right above it, we can focus and type in it, and the view would not scroll).
So the question is:
Why does the "system" push the content up when editing a text-field that's place right "behind" where the black bar is supposed to be? Is it because the black bar is not completely removed yet? Do we need to do something to "completely" remove the black bar? Do we need to force iOS to recalculate the size of the keyboard? or what exactly?
Is this mechanism (pushing up the view) implemented by iOS's UIWebView, or by Phonegap?
Is there any phonegap app that has solved this problem?
replace
[subviewWhichIsPossibleFormView removeFromSuperview];
with
UIScrollView *webScroll = [webView.subviews lastObject];
CGRect newFrame = webScroll.frame;
float accesssoryHeight = subviewWhichIsPossibleFormView.frame.size.height;
newFrame.size.height += accesssoryHeight;
[subviewWhichIsPossibleFormView removeFromSuperview];
[webScroll setFrame:newFrame];
it resize the content scroll view for the amount of missing accessory space. It is as far using "private API" as the other code. In detail it isn't using private API directly but if Apple decide to change how a view appears (in this case Keyboard and WebView) then it will crash.
For example if they rename UIWebFormAccessory, your code will not work anymore.
EDIT:
on iOS 5.0+ you can call webView.scrollView directly. So you can split the code to have a pre iOS 5 fallback:
UIScrollView *webScroll;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
webScroll = webView.scrollView;
} else {
webScroll = [webView.subviews lastObject]; // iOS 2.x (?) - 4.x
// make sure this code runs appropriate on older SDKs
}
This worked for me: https://github.com/don/KeyboardToolbarRemover
You will have to know though, there is no Cordova.plist file as of Phonegap 2.3.0 - instead edit your config XML file with the following:
<plugin name="KeyboardToolbarRemover" value="KeyboardToolbarRemover" />
in the branch

iPhone/iPad Keyboard Dimming

I am writing a universal app that will be used primarily at night. I will need to display a keyboard but do not want the light colors of the keyboard to blind the user and/or spoil their night vision. I do not want to have to go through the trouble to creating a custom keyboard so I thought a solution might be to place a UIView over the keyboard and give it a black background color with an alpha of 0.5 or something however, I can not figure out how to get a UIView to cover the keyboard. Does anyone know how to do this? Does Apple allow this?
The keyboard is found as a subview of a new window that is added when it appears. Finding it is a little hacky and fragile (will need checking at new iOS versions, as it has changed before) but it does work and it is allowed (I do exactly this for a night mode in an app that is on the app store).
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1]; // This assumes you aren't adding any new windows yourself
for(UIView *keyboard in tempWindow.subviews)
{
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES) // This was different in an earlier version of iOS, and may well change again in the future!
{
[keyboard addSubview:maskView];
break;
}
}
This is done inside the method that responds to the UIKeyboardDidShowNotification object. I've not tried it on the iPad, this is iPhone code only.
The mask view is, as you say, just a plain view with a black background and some transparency. You can also use the alert keyboard style which gives a black space in between the keys.
This method does not prevent the little key flashes (the larger keys that pop up when you tap a key) from being at full brightness, unfortunately.
try applying the required changes on inputView property of UITextFiled/UITextArea (the one being used).

UISwitch - change from on/off to yes/no

does anyone know of a way I can change the text label for on and off to yes and no.
I did it with
((UILabel *)[[[[[[switchControl subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:0]).text = #"Yes";
((UILabel *)[[[[[[switchControl subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:1]).text = #"No";
However, with the release of iOS 4.2, this is no longer supported (this probably wasn't recommended by Apple anyway)
My client is insisting on yes/no switches. I'd appreciate any advice!
many thanks
Hurrah! From iOS 6, it's possible to specify an image to be used for the on / off states, respectively. So, this can be used to display a YES / NO image (or whatever image representing the text you would prefer to use instead of the previously limited ON / OFF).
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0"))
{
[mySwitch setOnImage: [UIImage imageNamed:#"UISwitch-Yes"]];
[mySwitch setOffImage:[UIImage imageNamed:#"UISwitch-No"]];
}
The images should be 77 px wide, 27 px high, and the text (one image for each state) should be horizontally centred within that 77 px width. I use transparent backgrounds for the text, so I can still make use of the tint for the background, which still works with this.
Of course, it would seem easier to just supply text, rather than having to use an image of text, but I'm certainly grateful for this new option, at least.
You need to implement your custom UISwitch for that. Or use one of already implemented :) (check this SO question and this post)
Vladimir answer is great, but in my humble opinion there is an even better implementation here: https://github.com/domesticcatsoftware/DCRoundSwitch.
Besides setting a custom text, it is easier to change the size and color of the UISwitch and you get a sharper result.
It is released under an MIT license. Have a look!
It turns out that you can create a custom UISwitch with the following items:
A UIScrollView
A UIButton
Two UILabels
A background image
A Boolean value
First you will need to add QuartzCore.framework to your project and #import <QuartzCore/QuartzCore.h> to your view controller.
Next add the UIScrollView to your view using Interface Builder. The ScrollView will be your custom UISwitch.
Next add the button and the two labels to your ScrollView. One label will be for "yes" the other for "no".
Add the image to the button and set its type to custom. This is the image I use:
Position the labels over the blue and white area of the image. Adjust the ScrollView so it is just big enough to show the blue part of the image and the thumb nob.
Add the following line to viewDidLoad:
self.mySwitch.layer.cornerRadius = 13.5;
mySwitch is the name of the ScrollView and 13.5 is half the height of the ScrollView. The above statement changes the ScrollView to have rounded ends like the UISwitch.
To make the custom switch active you will need to tie the buttons "Touch Up Inside" event to an IBAction. Here is the code I use in the event handler:
-(IBAction)mySwitchButton:(id)sender {
self.myValue = !self.myValue;
CGPoint scrollPoint = CGPointMake((self.myValue)? 43.0: 0, 0.0);
[mySwitch setContentOffset:scrollPoint animated:YES];
}
Where myValue is the boolean variable that contains the state of your switch and 43.0 is the number of points you will have to move the image over to put the switch in the off position.
That is all there is to it!
From iOS 6, it's possible to specify an image to be used for the UISwitch on / off states, but NOT the text.
This will lead trouble when internationalization is required because translators
have to provide an image text for each language, not text only.
Moreover, the size of the UISwitch image is fixed, limiting the text length.
Because of the above reasons, I like the JSWilson's answer: simple and flexible.
To relieve developers of the need to manually add the required controls, I coded a custom CRDScrollSwitch class that you can find at my GitHub repository:
https://github.com/corerd/CRDScrollSwitch

Displaying Map ONLY when the button is clicked in Xcode

I am developing an iPhone application using XCode and I am kinda stuck with the functionality described in the subject of this post.
I want the map(using MapKit) to only load and display after I click a button. So, what code should I have under that my "(IBAction) showMap" function?
Whatever I could find online talks about unhiding the map. I want to only load the map when a button is clicked rather than loading the map in the background and simply unhiding it the click of the the button. Thanks !
~Susanth
Your button click should open a new view, which contains Map. Since that view does not exist until it's loaded (viewDidLoad, viewWillAppear), you are not loading map or displaying it beforehands.
- (IBAction)showMap:(id)sender
{
self.mapController = [[MyMapViewController alloc]
initWithNibName:#"MyMapViewController" bundle:nil];
[self.mainView addSubview:mapController.view];
}
Many ways to do it... It takes time to load a map, so you might still consider loading it at background. Looks better (faster) for end-user.
use the below concept.
-(IBAction) showMap:(id)sender
{
// Add your Map to current view
[self.view addsubview:YOUR_MAPVIEW];
}
-(IBAction) hideMap:(id)sender
{
[YOURMAPVIEW removeFromSuperView];
}
Here you can create the MapView either from XIB file or by writing code.
Hope this helps.
Jim.

iphone UITextView does not support data detectors when the text view is editable

I am getting an interesting warning at build time (iPhone simulator) that gives the following:
EditView.xib:35:0 UITextView does not support data detectors when the text view is editable.
This is basically non existent on google and I would like to remove it.
My editview.xib has a textview where I write notes into it. Is there any more info that is needed?
I have four different Xibs with similar TextViews that are used for notes as well. I was getting the same warnings. The suggestion to disable the "Detects Phone Numbers" and "Detects Links" does removes the warnings. However, I wanted my users to still have the ability to use the detectors in my notes.
This is how I solved the issue in my app:
In IB: I deselected the two properties for the TextView. -(which does stop the build warnings).
In my - (void)viewDidLoad { I set the properties of the textView to the following:
myTextView.dataDetectorTypes = UIDataDetectorTypeAll; which enables the data detectors of all types (phone numbers and url addresses).
In my View Controller's: -(void)textViewDidBeginEditing:(UITextView *)sender {
method, I turned the data detectors back OFF using: myTextView.dataDetectorTypes = UIDataDetectorTypeNone
Then taking advantage of the -(void)textViewDidEndEditing:(UITextView *)sender {
method, I turned them back ON using: myTextView.dataDetectorTypes = UIDataDetectorTypeAll;
This method disables the data detectors when the user is editing the UITextView and turns the data detectors back ON when the user is finished editing. This Fix allowed for selection of the phone numbers and URL from within the textView, so that I did not loose the function.
I found the following in the Apple Docs on the DataDetectors for UITextView: after playing around with the UITextView for a while, hope it helps.
UIDataDetectorTypes:
Defines the types of information that can be detected in text-based content.
Types:
UIDataDetectorTypePhoneNumber;
UIDataDetectorTypeLink;
UIDataDetectorTypeNone;
UIDataDetectorTypeAll;
Update: 11-5-2010;
Extra Note:
Data detectors are not permitted if UITextView is "Editable", because there would be too many variables to track users changes to text as well as touches with trying to execute phone call or links.
Solution:
Load the TextView with self.textView.editable = NO; and set you UIDataDetector's based on the types I listed above. This way if the user wants to "select" web address or phone number etc, the delegate can handle. When you need your user to edit the textView, then turn ON the self.textView.editing = YES; & remove your UIDataDetectors accordingly. This should assure no errors or warnings during compiling.
Special Consideration:
Be sure to first remove the datadectors when re-enabling, then enable "editing = YES;"...The order is important no to enable editing if UIdatadetectors are still assigned.
Therefore, the sequence order should be something like this...
To Edit textView: 1. remove data detectors, 2. then enable editing = YES.
To Use DataDetectors: 1. Disable Editing = NO; 2. then add data detectors.
I was seeing this warning as well. Here's how I fixed it:
In the xib file in Interface Builder, select your text view, and bring up the attributes inspector. Make sure that "Detects Phone numbers" and "Detects Links" are both UNCHECKED.
I had "Detects Links" checked, and turns out that's what was causing the warning. Basically, if the textview is editable, you don't want these auto-detect features turned on.
So Wordy!
textView.editable = NO;
textView.dataDetectorTypes = UIDataDetectorTypeAll;
the URL address must start with "http://", otherwise the textview cannot detect it.
I thought about trying to use a Tap-Gesture-Recognizer with "delaysTouchesBegan = YES" and "cancelsTouchesInView = NO"
It is still quite easy to solve!
Load view with editable disabled as well as UIDataDetectorTypeAll or the types of links you want to detect. Then add a GestureRecognizer:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(editTextRecognizerTabbed:)];
recognizer.delegate = self;
recognizer.numberOfTapsRequired = 1;
[self.textViewNotes addGestureRecognizer:recognizer];
So you can change settings within this method:
- (void) editTextRecognizerTabbed:(UITapGestureRecognizer *) aRecognizer;
{
self.textViewNotes.dataDetectorTypes = UIDataDetectorTypeNone;
self.textViewNotes.editable = YES;
[self.textViewNotes becomeFirstResponder];
}
And at least you have to change the edit and detections settings back after user has finished the text input:
- (void)textViewDidEndEditing:(UITextView *)textView;
{
self.textViewNotes.editable = YES;
self.textViewNotes.dataDetectorTypes = UIDataDetectorTypeAll;
}
works lika a charm!
Data detectors for the UITextView would be for copy and paste. Since you are setting it as editable, copy/paste shouldn't be allowed where you think paste should, but copy shouldn't.
Simplenote somehow does this on iOS 4. (There's a free/lite version in case you wanna try.)
It acts a little bit different:
When tapping on one of the highlighted parts, it still starts the editing, and won't follow the link.
But when you tap-and-hold on a detected dataTpye, it shows yout the menu for calling, open the link or whatever.
Also, when tapping inside the text the editing really starts at the place you tapped.
So they somehow remove the dataDectectors, enable editing AND get the touches forwarded to the editable UITextview AFTER the tap is recognized.
Any ideas how to do that?
I thought about trying to use a Tap-Gesture-Recognizer with "delaysTouchesBegan = YES" and "cancelsTouchesInView = NO"
So I can remove the dataConnectorTypes and set it editable on the action method of the recognizer,
and hopefully the touches to the UITextview are delivered AFTER that.
But haven't had time to test it so far.