UISwitches, need an explanation - objective-c

How do the switches work in XCode4? how do i check which properties are available to me for the switches?
i am trying to check the state of a switch and make a label change according to the state. Something like this:
-(IBAction)clickedOnSwitch:(id)sender {
NSString *switchState = [[NSString alloc]init];
if (mySwitchIsOn) {
switchState = #"switch is On";
}
else
{
switchState = #"switch is Off";
}
myLabel.text = switchState;
[switchState release];
}

Take a look at the UISwitch class reference either on the web or in the Xcode documentation browser.

Related

Different data for sharing providers in UIActivityViewController

I'm trying to use an UIActivityViewController with one long NSString as the data. If I put a string > 140 characters, the tweet sheet in it does not display the string. And if I truncate the string before giving it to the controller, all of the UIActivities have the truncated string. I don't want Facebook or Message to be truncated.
Is there a way to give different strings to different UIActivities?
Thank you!
(e.g. Marco Arment's The Magazine app does this by having a truncated string followed by #TheMagazineApp in UIActivityPostToTwitter, and other stuff in other UIActivities.)
I think this is what you're looking for: Custom UIActivityViewController icons and text.
You should be able to provide different data for each activity type.
Hope this helps somebody. It's pretty straightforward if you subclass UIActivityItemProvider:
#interface MyActivityItemProvider : UIActivityItemProvider
#end
#implementation MyActivityItemProvider
- (id)item
{
// Return nil, if you don't want this provider to apply
// to a particular activity type (say, if you provide
// print data as a separate item for UIActivityViewController).
if ([self.activityType isEqualToString:UIActivityTypePrint])
return nil;
// The data you passed while initialising your provider
// is in placeholderItem now.
if ([self.activityType isEqualToString:UIActivityTypeMail] ||
[self.activityType isEqualToString:UIActivityTypeCopyToPasteboard])
{
return self.placeholderItem;
}
// Return something else for other activities. Obviously,
// you can as well reuse the data in placeholderItem here.
return #"Something else";
}
#end
Then pass its instance with an array of activity items to UIActivityViewController:
MyActivityItemProvider *activityItem =
[[MyActivityItemProvider alloc] initWithPlaceholderItem:#"Your data"];
NSArray *sharingItems = [NSArray arrayWithObjects:
activityItem, _myUITextView.viewPrintFormatter, nil];
UIActivityViewController *activityController =
[[UIActivityViewController alloc]
initWithActivityItems:sharingItems applicationActivities:nil];
This can be easily done by using the optional activityType property from the UIActivityItemProvider object. That property returns a UIActivityType, so you can do something like:
class PhotoActivityItemProvider: UIActivityItemProvider {
...
override var item: Any {
guard let activityType = self.activityType else {
return photoURL.absoluteString
}
if activityType == .mail || activityType == .message {
return "The photo link is \(photoURL.absoluteString)."
}
...
}
More information in my blog post: https://www.whitesmith.co/blog/control-what-youre-sharing/
You can create a class that conforms to UIActivityItemSource and then pass its instance with an array of activity items to UIActivityViewController:, as #Mu-Sonic suggested.
If you want to know in which platform is the user sharing and return any specific data dependent on the tapped platform, override public func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any?

Using a method in Objective-C cocoa

I'm having trouble with something very basic. I want to call this action:
- (IBAction)changeGreeting:(id)sender {
self.userName = self.textField.text;
NSString *nameString = self.userName;
if ([nameString length]==0) {
nameString = #"World";
}
NSString *greeting = [[NSString alloc] initWithFormat:#"Hello, %#!", nameString];
self.label.text = greeting;
}
When the user presses return after entering text in the text field. This is what I have:
-(BOOL)textFieldShouldReturn:(UITextField *)theTextField{
if (theTextField == self.textField) {
[theTextField resignFirstResponder];
[changeGreeting];
}
return YES;
}
I'm not sure what to put where it says "changeGreeting." Think I'm missing the concept here. Thanks for any help.
Your syntax is wrong. Try this:
[self changeGreeting:self];
In Objective-C the syntax for sending messages (calling functions) is like this:
[receiver message];
Since you implement the changeGreeting: method in the same class as you're calling it from, the receiver will be self. As the parameter (sender) you usually pass the object that sends the message, but since you don't use it in your implementation of changeGreeting: it doesn't really matter what you pass there.
you called the changeGreeting function in wrong way
you should call it like
[self changeGreeting:nil];
Or if you want to track something from the textField then
[self changeGreeting:theTextField];
the sender will get theTextField as parameter if you need some processing on based on the textField.

Calling Obj-C Code from JavaScript via Console: Arguments get dropped?

Having a heck of a time with this one.
I've got a super-simple Cocoa app containing one WebView, a WebScripting API defined in the page, and a single NSObject defined on that API. When I turn on the debugger tools (in the embedded WebView), I can see the API on the JavaScript window object, and I can see my "api" property defined on that -- but when I call the API's "get" method, the arguments aren't being serialized -- when the Obj-C method gets called, the arguments are missing. See below, which hopefully illustrates:
I've combed through the docs, I've (apparently) set the appropriate methods to expose everything that needs to be exposed, and I can see the method being called. There has to be something stupid I'm missing, but as a relative newbie to this environment, I'm not seeing it.
Thanks in advance for your help!
Have you set WebKitDeveloperExtras to YES in your default user defaults when you send -[NSUserDefaults registerDefaults:]?
Depending on what version of Xcode you're using you could be getting a known error. If you're using LLDB on anything but the most recent version, it might not be giving you the right variables in the debugger. The solution has been to use GDB instead of LLDB until Apple fixes the problem. But I think they fixed the problem in the latest version. I'd change the debugger to use GDB and see if you're getting the right variables in Xcode. (Product-> Edit Scheme...-> Run -> Debugger). I came across this problem in iOS, though, so I don't know its applicability to OSX. Worth a try anyway.
I originally came across the problem here: https://stackoverflow.com/a/9485349/1147934
I process javascript in the main thread of my app from a local file stored in the apps directory. I check for beginning and ending tokens for the js functions I am executing and whether the function contains a variable.
Hopefully this can give you some good ideas for your issue. You could also do alerts in the js to see if the values post correctly as you run the app (I am sure you thought of that already, but it's worth mentioning.) Happy coding! I hope this helps!
in the .h file define:
NSMutableString *processedCommand;
NSArray *commandArguments;
In the .m file:
// tokens
#define kOpenToken #"<%%"
#define kCloseToken #"%%>"
// this will throw
-(void)executeJScriptCommand:(NSString *)aCommand {
[self performSelectorOnMainThread:#selector(executeThisCommand:) withObject:aCommand waitUntilDone:YES];
}
// this will throw
-(NSString *)executeCommand:(NSString *)command {
NSString *aCommand = [[[command stringByReplacingOccurrencesOfString:kOpenToken withString:#""]
stringByReplacingOccurrencesOfString:kCloseToken withString:#""]
stringByTrimmingLeadingAndTrailingWhitespaces];
if ([aCommand hasPrefix:#"="])
{
// variable. get value
[self getVariableFromCommand:aCommand];
}
else {
[self executeThisCommand:aCommand];
}
NSString *returnValue = [NSString stringWithString:processedCommand];
self.processedCommand = nil;
self.commandArguments = nil;
return returnValue;
}
-(void)executeThisCommand:(NSString *)aCommand {
BOOL hasError = NO;
// clear result
self.processedCommand = nil;
self.commandArguments = nil;
BOOL isFromJS = NO;
NSString *function = nil;
NSMutableArray *commandParts = nil;
#try {
// first, break the command into its parts and extract the function that needs to be called, and the (optional) arguments
commandParts = [[NSMutableArray alloc] initWithArray:[aCommand componentsSeparatedByString:#":"]];
if ([[[commandParts objectAtIndex:0] lowercaseString] isEqualToString:#"js-call"]) {
isFromJS = YES;
[commandParts removeObjectAtIndex:0];
}
// get our function, arguments
function = [[commandParts objectAtIndex:0] retain];
[commandParts removeObjectAtIndex:0];
if ([commandParts count] > 0){
if (isFromJS == YES) {
NSString *arguments = [[commandParts objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([arguments length] > 0) {
self.commandArguments = [arguments JSONValue];
}
}
else {
self.commandArguments = [NSArray arrayWithArray:commandParts];
}
}
// build invoke
SEL sel = NSSelectorFromString(function);
if ([self respondsToSelector:sel]) {
[self performSelectorOnMainThread:sel withObject:nil waitUntilDone:YES];
// using invocation causes a SIGABORT because the try/catch block was not catching the exception.
// using perform selector fixed the problem (i.e., the try/catch block now correctly catches the exception, as expected)
}
else {
[appDelegate buildNewExceptionWithName:#"" andMessage:[NSString stringWithFormat:#"Object does not respond to selector %#", function]];
}
}
#catch (NSException * e) {
hasError = YES;
[self updateErrorMessage:[NSString stringWithFormat:#"Error processing command %#: %#", aCommand, [e reason]]];
}
#finally {
[function release];
[commandParts release];
}
if (hasError == YES) {
[appDelegate buildNewExceptionWithName:#"executeThisCommand" andMessage:self.errorMessage];
}
}
// this can return nil
-(NSString *)getQueryStringValue:(NSString *)name {
NSString *returnValue = nil;
if (queryString != nil) {
returnValue = [queryString objectForKey:[name lowercaseString]];
}
return returnValue;
}

Can't show the right URL in my iPad simulator

I'm building an iPad app and that's a browser. I have a little problem because in a text field, I can write any web direction, such http://www.google.com/. The problem is that when I change the page, at, for example, http://www.apple.com/ , it stills says google. I have written the code, but I don't know why it doesn't work!
-(void)currentURL{
int i= 0;
while (i == 0) {
url = [request URL];
NSLog(#"%#", url.absoluteString);
textfield.text = url.absoluteString;
}}
Please I need some help!
replace this:
textfield.text = url.absoluteString;
with this:
if(textfield)
{
if(url)
{
textfield.text = [url absoluteString];
} else {
NSLog( #"my request or URL is nil");
}
} else {
NSLog( #"I didn't set my textfield");
}
You need to implement the web view delegate which will tell you when the page inside the web view changes, e.g. when the user clicks a link. You can then use the delegate methods to update your text field to the new URL.
if you've done that and your textfield isn't updating, you've probably forgotten to connect your textfield in your nib file to the textfield outlet of your class, so your self.textfield property is nil and setting its text does nothing.

Uiswitch on/off

m new to objective-c, i have made a application of login page in which i have used UISwitch to remember d login details if switch is in on mode. i have done with to remember the login details but problem is that how to use the switch on/off condition. Thanx in advance
The easiest solution of all :)
if (switchValue.on){
//Remember Login Details
}
else{
//Code something else
}
You would add a conditional statement somewhere in your code depending on the switch's on property. Let's say, for example, that you remember login details in a method called rememberLoginDetails. What you would do is, when some action is triggered (the user leaves the login page, for example):
if([yourSwitch isOn]) {
[self rememberLoginDetails];
} else {
// Do nothing - switch is not on.
}
The important method here is the isOn method for the UISwitch yourSwitch. isOn is the getter for the switch's on property, which is a BOOL property containing YES if the switch is on, and NO if it is not.
For more information, you can see the UISwitch class reference, specifically the part about isOn.
if you want to remember the login details just the moment where the user TURN ON the switch, you can done it by create an Action.
- (IBAction)yourSwitch:(id)sender {
if([sender isOn]){
//do your stuff here
}else{
}
}
I believe the code needs to be this:
if([yourSwitch isOn] == YES) {
[self rememberLoginDetails];
} else {
// Do nothing - switch is not on.
}
This is another solution, if your UISwitch is in a tableView
1 add this code in "tableView:cellForRowAtIndexPath:" method
[switchControl addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
2 add this method
- (void) switchChanged:(id)sender {
UISwitch *switchControl = sender;
NSLog( #"The switch is %#", switchControl.on ? #"ON" : #"OFF" );
}
if(switchValue.isOn){
[switchValue setOn:NO];
} else {
[switchValue setOn:YES];
}
i had the same problem, i had the name of the UISwitch = Selected
i changed it to another name and it worked.
This is another solution for that question.
if (switchValue.on == YES)
{
// Code...
}
else
{
// Other code...
}