Please can anyone tell me why this piece of code isn't working? I've got a dictionary which contains UIViews with tables inside associated with the keys which are the names of the corresponding buttons (there are a lot of them). So what I actually want to do is to change the view visibility on the corresponding button click. But the issue is that the expression to do that is not accepted by Xcode and I get the Expected Identifier error.
- (IBAction)choosingButtonClicked:(id)sender {
if ([sender currentTitle]) {
[(UIView *)[self.selectionTables objectForKey:[sender currentTitle]]].hidden = ![(UIView *)[self.selectionTables objectForKey:[sender currentTitle]]].isHidden;
}
}
First of all, with all due respect, I agree with trojanfoe comments. Its not working because its not properly written.
Now, lets try to streamline it with below code:
- (IBAction)choosingButtonClicked:(id)sender {
NSString *title = [sender currentTitle];
if (title) {
UIView *selectionView = (UIView *)self.selectionTables[title];
selectionView.hidden = !selectionView.isHidden;
}
}
Your code is too complex, because of that even the author can't understand it. If we re-write your code using local variables, it will look like:
- (IBAction)choosingButtonClicked:(id)sender
{
NSString *title = [sender currentTitle];
if (title)
{
UIView *tempView = (UIView *)[self.selectionTables objectForKey:title];
[tempView].hidden = ![tempView].isHidden;
}
}
If you check the code now, you can see that the following code is causing the issues:
[tempView].hidden = ![tempView].isHidden;
Change your method like:
- (IBAction)choosingButtonClicked:(id)sender
{
NSString *title = [sender currentTitle];
if (title)
{
UIView *tempView = (UIView *)[self.selectionTables objectForKey:title];
tempView.hidden = !(tempView.isHidden);
}
}
Related
Sorry if the title is not really clear, I will explain it here anyway.
I've got 2 files: SelectPostIt.xib and PostIt.xib .
On my main.storyboard i've got a UIButton which, when someone push it, it create a new SelectPostIt. This one is non editable.
The principle is that when I doubleTap a selectPostIt, a new PostIt appears:
-(IBAction)doubleTap:(UITapGestureRecognizer *)recognizer {
if(!_isEdited){
_isEdited = true;
PostIt *editPostIt = nil;
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:#"PostIt" owner:self options:nil];
for (id object in objects)
{
if ([object isKindOfClass:[PostIt class]])
{
editPostIt = object;
}
}
editPostIt.frame = CGRectMake(10,10, 400, 400);
[editPostIt setParent:self];
[self.superview addSubview:editPostIt];
}}
So normally, the selectPostIt is seated as Parent of the the new Post it in: [editPostIt setParent:self]; , right? I already have (in PostIt.m):
-(void)setParent:(SelectPostIt*)value{
_parent = value;
}
With a property(weak, nonatomic) SelectPostIt* parent;in my PostIt.h.
And then, when I double tap on the PostIt, it will disappear but also change the value of the SelectPostIt who created him with this method:
-(IBAction)doubleTap:(UITapGestureRecognizer *)recognizer{
NSString *string = [self.titre text];
//NSLog(#"string: %#", string );
[_parent setTitre:string];
string = [self.commentaire text];
//NSLog(#"string: %#", stringFromTextField );
[_parent setCommentaire:string];
[_parent setIsEdited:true];
if(_parent == NULL)
NSLog(#"Pas de parents" );
if(_parent == nil)
NSLog(#"Pas de parents" );
[self removeFromSuperview];
}
I made some test and the String are good but, the value of the SelectPostIt aren't changed (the good point is that the PostIt disappear at least haha).
So if someone could help me on where I am wrong it could be nice, thanks in advance :)
That's not the exact answer but that's a point I think I must dig on:
I've added in my PostIt.m:
#synthesize parent;
And changed :
[parent setIsEdited:true]
To : (that was a mistake from me here)
[parent setIsEdited:false]
So now, my PostIt.m 's doubleTap method looks like:
-(IBAction)doubleTap:(UITapGestureRecognizer *)recognizer{
NSString *string = [self.titre text];
[parent setTitre:string];
string = [self.commentaire text];
[parent setCommentaire:string];
[parent setIsEdited:false];
[self removeFromSuperview]; }
And from now, when I close a editPostIt , when I doubleTap on the selectPostIt a new editPostIt is created, and I wasn't able to before. That's mean that the boolean from the selectPostIt has been changed by the closure of the editPostIt .
So I think from now that, this is good:
-(IBAction)doubleTap:(UITapGestureRecognizer *)recognizer{
NSString *string = [self.titre text];
[parent setTitre:string];
string = [self.commentaire text];
[parent setCommentaire:string];
[parent setIsEdited:false];
[self removeFromSuperview]; }
But I need to "reload" (?) the selectPostIt or something else so it could take the new data? I dont really know...
Aster finding myself in the situation of wanting to disable a UIPickerView component and not finding any answers that uses the default functionality but tries to go around it by using labels or multiple UIPickerViews, I start poking around the UIPickerView structure in order to find a more direct approach to solve the problem by using the OS already present functionality.
So these is my answer, what I found by trial and error, and the way that I am using it:
The method:
- (void)dissableUIPickerViewComponent:(int)componentToDissable forPickerView:(UIPickerView *)pickerView{
NSArray *pickerViews = [[NSArray alloc] initWithArray:[pickerView subviews]];
UIView *mainSubview;
for (int count = 0; count < pickerViews.count; count++) {
UIView *temp = [pickerViews objectAtIndex:count];
if (temp.frame.size.height > 100) {
mainSubview = temp;
}
}
NSArray *componentSubview = [mainSubview subviews];
while ([[[[componentSubview objectAtIndex:componentToDissable] subviews] firstObject] superview].gestureRecognizers.count) {
[[[[[componentSubview objectAtIndex:componentToDissable]subviews]firstObject]superview] removeGestureRecognizer:[[[[[componentSubview objectAtIndex:componentToDissable]subviews]firstObject]superview].gestureRecognizers objectAtIndex:0]];
}
}
Best place to call:
- (void)viewDidAppear:(BOOL)animated{
[self dissableUIPickerViewComponent:0 myPickerView];
}
I hope these will help others that found themself in the same position that I did :)
How can i fix this kind of problems
here is some code
BOOL missed = NO;
if (elem.lastCall.lastMissedEvent) {
if ([elem.status intValue] == 3 && [elem.timeStamp compare:elem.lastCall.lastMissedEvent] != NSOrderedAscending) {
missed = YES;
}
}
SCBubbleViewOut *bubble = nil;
if ([cell.bubbleView isKindOfClass:[SCBubbleViewOut class]]) {
bubble = (SCBubbleViewOut *) cell.bubbleView;
}
or here is some more code snipet
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *userid = [members objectAtIndex:indexPath.row];
BOOL itsMe = NO;
if ([userid isEqualToString:[SCUserProfile currentUser].userid]) {
itsMe = YES;
[self performSegueWithIdentifier:#"SCUserProfileControllerSegue" sender:self];
}
else
{
[self showFriendDetailForUserid:userid];
}
}
from these cases i get
Value stored to "BOOL" is never read;
BOOL = itsMe , missed and bubble.
Any help is highly appreciated
Thanks in Advance.
Well, you are storing some value into a variable "missed", and you are never using the value stored. So the compiler is wondering why you are doing this, because it is pointless, and the compiler assumes that maybe you wanted to do something else.
If you stored the variable for example so that you can view it in the debugger, add a line
(void) missed;
That tells the compiler "yes, I know I store a value and I'm not using it, leave me alone". On the other hand, if that's not the case then you need to figure out what you actually wanted to do. The compiler doesn't know, and we don't know. The compiler just says "this doesn't look right", and I can only agree with it.
I have a story board that has a UITextField, UIButton, UIImage, and UILabel to display the images in an array. If you type the correct name for the image file into a text field. So, the problem is that once the text field input does not match, it should update the UILabel to display "Result not found", but it doesn't.
#import "ViewController.h"
#interface ViewController ()
{
myClass *myNewClass;
NSMutableArray *picArray;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
picArray = [#[#"Button_Red",#"Button_Green"]mutableCopy];
}
- (IBAction)displayImageAction:(id)sender
{
NSString *titleSearched = self.textSearchField.text;
NSString *titleNotHere = self.notFoundLabel.text;
//Declare a bool variable here and set
BOOL variable1;
for (int i = 0; i < picArray.count; i++)
{
NSString *currentPic = picArray[i];
if ([titleSearched isEqualToString:currentPic])
{
variable1 = YES;
}
}
if (variable1 == YES) {
//this works fine displays the image
self.outputImage.image = [UIImage imageNamed: titleSearched];
[self.textSearchField resignFirstResponder];
} else {
//problem is here its not showing when input for the array is not equal it should display a message label "Result Not Found" but it remains blank on the IOS simulator
titleNotHere = [NSString stringWithFormat:#"Result Not found"];
[self.textSearchField resignFirstResponder];
}
}
//Get rid of the texfield when done typing
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Retract keyboard if up
[self.textSearchField resignFirstResponder];
}
Your problem is that
titleNotHere = [NSString stringWithFormat:#"Result Not found"];
simply sets the method variable titleNotHere.
What you want is
self.notFoundLabel.text=#"Result Not found";
You will also want
self.notFoundLabel.text=#"";
when the result is found.
I think you will have to SET the value to the variable
self.notFoundLabel.text = [NSString stringWithFormat:#"Result Not found"]
or
self.notFoundLabel setText:[NSString stringWithFormat:#"Result Not found"]
UILabel.text = #"whatever..." is actually converted into [UILable setText:#"whatever..."].
NSString *labelText = UILabel.text has to be thought as NSString *labelText = [UILabel text];
This:
NSString *titleNotHere = self.notFoundLabel.text;
stores the text from the label into a variable, but updating that variable again will not change the label text - it only changes what that variable points to.
You need to explicitly update the label text:
self.notFoundLabel.text = #"Result Not found";
note also that this uses a string literal - you don't need to use a format string as you aren't adding any parameters to it.
Also, when checking booleans, don't use if (variable1 == YES) {, just use if (variable1) { (it's safer).
With the following setup
....
MyUIMenuItem *someAction = [[MyUIMenuItem alloc]initWithTitle : #"Something" action : #selector(menuItemSelected:)];
MyUIMenuItem *someAction2 = [[MyUIMenuItem alloc]initWithTitle : #"Something2" action : #selector(menuItemSelected:)];
....
- (IBAction) menuItemSelected : (id) sender
{
UIMenuController *mmi = (UIMenuController*) sender;
}
How to figure out which menu item was selected.
And don't say that you need to have two methods... Thanks in advance.
Okay, I've solved this one. The solution isn't pretty, and the better option is "Apple fixes the problem", but this at least works.
First of all, prefix your UIMenuItem action selectors with "magic_". And don't make corresponding methods. (If you can do that, then you don't need this solution anyway).
I'm building my UIMenuItems thus:
NSArray *buttons = [NSArray arrayWithObjects:#"some", #"random", #"stuff", nil];
NSMutableArray *menuItems = [NSMutableArray array];
for (NSString *buttonText in buttons) {
NSString *sel = [NSString stringWithFormat:#"magic_%#", buttonText];
[menuItems addObject:[[UIMenuItem alloc]
initWithTitle:buttonText
action:NSSelectorFromString(sel)]];
}
[UIMenuController sharedMenuController].menuItems = menuItems;
Now your class that catches the button tap messages needs a few additions. (In my case the class is a subclass of UITextField. Yours might be something else.)
First up, the method that we've all been wanting to have but that didn't exist:
- (void)tappedMenuItem:(NSString *)buttonText {
NSLog(#"They tapped '%#'", buttonText);
}
Then the methods that make it possible:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
NSString *sel = NSStringFromSelector(action);
NSRange match = [sel rangeOfString:#"magic_"];
if (match.location == 0) {
return YES;
}
return NO;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
if ([super methodSignatureForSelector:sel]) {
return [super methodSignatureForSelector:sel];
}
return [super methodSignatureForSelector:#selector(tappedMenuItem:)];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
NSString *sel = NSStringFromSelector([invocation selector]);
NSRange match = [sel rangeOfString:#"magic_"];
if (match.location == 0) {
[self tappedMenuItem:[sel substringFromIndex:6]];
} else {
[super forwardInvocation:invocation];
}
}
One would expect that the action associated with a given menu item would include a sender parameter that should point to the chosen menu item. Then you could simply examine the title of the item, or do as kforkarim suggests and subclass UIMenuItem to include a proeprty that you can use to identify the item. Unfortunately, according to this SO question, the sender parameter is always nil. That question is over a year old, so things may have changed -- take a look at what you get in that parameter.
Alternately, it looks like you'll need to a different action for each menu item. Of course, you could set it up so that all your actions call a common method, and if they all do something very similar that might make sense.
Turns out it's possible to obtain the UIButton object (which is actually UICalloutBarButton) that represents UIMenuItem if you subclass UIApplication and reimplement -sendAction:to:from:forEvent:. Although only -flash selector goes through UIApplication, it's enough.
#interface MyApplication : UIApplication
#end
#implementation MyApplication
- (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event
{
// target == sender condition is just an additional one
if (action == #selector(flash) && target == sender && [target isKindOfClass:NSClassFromString(#"UICalloutBarButton")]) {
NSLog(#"pressed menu item title: %#", [(UIButton *)target titleLabel].text);
}
return [super sendAction:action to:target from:sender forEvent:event];
}
#end
You can save target (or any data you need from it) in e.g. property and access it later from your UIMenuItem's action.
And to make your UIApplication subclass work, you must pass its name as a third parameter to UIApplicationMain():
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, NSStringFromClass([MyApplication class]), NSStringFromClass([YOUR_APP_DELEGATE class]));
}
}
This solution works on iOS 5.x-7.0 as of post date (didn't test on older versions).
ort11, you might want to create a property of myuimenuitem and set some sort of Tag. Thay way the object of sender could be recognized by its tag it. In Ibaction then you can set a switch statement that can correspond to each sender.tag and work throught that logic. I guess thats the simplest way to go.