The below code for the most part works when selecting items, the bar button enables, but as soon as I unselect 1 with say 3 still selected, it disables.
How can I use the below code to disable when the count reaches 0 items selected?
- (void)assetsTableViewCell:(WSAssetsTableViewCell *)cell didSelectAsset:(BOOL)selected atColumn:(NSUInteger)column
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// Calculate the index of the corresponding asset.
NSUInteger assetIndex = indexPath.row * self.assetsPerRow + column;
WSAssetWrapper *assetWrapper = [self.fetchedAssets objectAtIndex:assetIndex];
assetWrapper.selected = selected;
// Update the state object's selectedAssets.
[self.assetPickerState changeSelectionState:selected forAsset:assetWrapper.asset];
// Update navigation bar with selected count and limit variables
dispatch_async(dispatch_get_main_queue(), ^{
if (self.assetPickerState.selectionLimit) {
self.navigationItem.title = [NSString stringWithFormat:#"%# (%lu/%ld)", [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName], (unsigned long)self.assetPickerState.selectedCount, (long)self.assetPickerState.selectionLimit];
}
});
}
Below is what needs adjusting.
if (selected == 1) {
self.navigationItem.rightBarButtonItem.enabled = YES;
} else if (selected == 0) {
self.navigationItem.rightBarButtonItem.enabled = NO;
}
selected will give you the state of the current asset so it wouldn't be wise to check this.
We need to check for some kinda global thing; basically to check for previous selections.
Looking at your navigationItem.title, it seems assetPickerState.selectedCount should do the trick.
So... maybe this?? (not sure but anyways...)
if (self.assetPickerState.selectedCount == 0) {
self.navigationItem.rightBarButtonItem.enabled = NO;
}
else {
self.navigationItem.rightBarButtonItem.enabled = YES;
}
Looks like you're only explicitly enabling the button when you have 1 selected (not more than that). Just going out on a whim but this might work (only disable if zero, otherwise enable it).
if (selected == 0) {
self.navigationItem.rightBarButtonItem.enabled = NO;
} else {
self.navigationItem.rightBarButtonItem.enabled = YES;
}
Related
I have created a view with segment control. So when I select No it should show another set of questions. I'm achieving this using tableview and constraints. I'm setting the correct constraints in code as well as in UI but the it shows only when I scroll the UI. This is the code through which I'm setting the constraint
- (void)segmentChanged:(id)sender
{
if ([sender isEqual:_TestedForPestiAntiBioticsToggle]) {
if (_TestedForPestiAntiBioticsToggle.selectedSegmentIndex == 1) {
//_percentOfAntiBodyTxt.hidden=YES;
//_percentagelbl.hidden=YES;
_ans3bConstraints.constant = 75;
}
else {
_percentOfAntiBodyTxt.text = #"";
//_percentOfAntiBodyTxt.hidden=NO;
//_percentagelbl.hidden=NO;
_ans3bConstraints.constant = 5;
}
}
}
The screenshot of the my layout is as follows
the layout
This is the image of my UI
This is the correct UI I get after scroll
This is the incorrect UI I get before scroll
I need to get the proper UI without scroll.
I just reloaded my table view and table data and it worked like charm. This is the code:
(void)segmentChanged:(id)sender
{
if ([sender isEqual:_TestedForPestiAntiBioticsToggle]) {
if (_TestedForPestiAntiBioticsToggle.selectedSegmentIndex == 1) {
_percentOfAntiBodyTxt.text = #"";
//_percentOfAntiBodyTxt.hidden=YES;
//_percentagelbl.hidden=YES;
_ans3bConstraints.constant = 75;
[self reloadTable];
[self.tableView reloadData];
}
else {
//_percentOfAntiBodyTxt.hidden=NO;
//_percentagelbl.hidden=NO;
_ans3bConstraints.constant = 5;
[self reloadTable];
[self.tableView reloadData];
}
}
}
I'm trying to add a gesture recognizer to specific tabBar item's subview. I can successfully add one to the tabBar itself, but not a specific index.
I was able to trick it into reacting based on a selectedIndex by implementing this in my AppDelegate:
[self.tabBar.view addGestureRecognizer:longPressNotificationsGR];
-(void)showFilterForNotifications:(UILongPressGestureRecognizer *)gesture {
if (self.tabBar.selectedIndex == 4) {
if (gesture.state == UIGestureRecognizerStateBegan) {
NSLog(#"Began");
} else if (gesture.state == UIGestureRecognizerStateEnded) {
NSLog(#"Ended");
}
}
}
Is there a better way? And yes I know this isn't what Apple had in mind but this is what I need for my particular project. I just feel like this isn't the best workaround, if there even is one, and i'm not sure how this will behave performance wide since its in the AppDelegate. But ultimately, I don't want to do it this way, I want to add it to the objectAtIndex:n so users can't just press and hold anywhere on the tabBar, even if 4 is the currently selected index. Right now users can tap & hold on index 1 icon, if 4 is selected, and the gesture methods get called. I want it to happen only if user is tapping & holding on objectAtIndex:n
You can get the UIView of a tab at a specific index with the following category method on UITabBar:
- (UIView*)tabAtIndex:(NSUInteger)index
{
BOOL validIndex = index < self.items.count;
NSAssert(validIndex, #"Tab index out of range");
if (!validIndex) {
return nil;
}
NSMutableArray* tabBarItems = [NSMutableArray arrayWithCapacity:[self.items count]];
for (UIView* view in self.subviews) {
if ([view isKindOfClass:NSClassFromString(#"UITabBarButton")] && [view respondsToSelector:#selector(frame)]) {
// check for the selector -frame to prevent crashes in the very unlikely case that in the future
// objects that don't implement -frame can be subViews of an UIView
[tabBarItems addObject:view];
}
}
if ([tabBarItems count] == 0) {
// no tabBarItems means either no UITabBarButtons were in the subView, or none responded to -frame
// return CGRectZero to indicate that we couldn't figure out the frame
return nil;
}
// sort by origin.x of the frame because the items are not necessarily in the correct order
[tabBarItems sortUsingComparator:^NSComparisonResult(UIView* view1, UIView* view2) {
if (view1.frame.origin.x < view2.frame.origin.x) {
return NSOrderedAscending;
}
if (view1.frame.origin.x > view2.frame.origin.x) {
return NSOrderedDescending;
}
NSLog(#"%# and %# share the same origin.x. This should never happen and indicates a substantial change in the framework that renders this method useless.", view1, view2);
return NSOrderedSame;
}];
if (index < [tabBarItems count]) {
// viewController is in a regular tab
return tabBarItems[index];
}
else {
// our target viewController is inside the "more" tab
return [tabBarItems lastObject];
}
return nil;
}
Then, you just need to add your gesture recognizer:
[[self.tabBarController.tabBar tabAtIndex:4] addGestureRecognizer:myGestureRecognizer];
I have four text fields in a ViewController, and want to disable the keyboard for two of them (textField1 and textField2).
I have tried implementing the following after assigning the text fields as delegates in viewDidLoad
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField) {
if ([self.textField1 isTouchInside] || [self.textField2 isTouchInside] {
return NO;
} else {
return YES;
}
}
However, this disables the keyboard for the ViewController completely, so it will not appear when trying to edit textField3 and textField4. How can I get around this problem?
For example, is there a way to refresh the run textFieldShouldBeginEditing method again after editing ends on a textField?
Also, I know I can create a label to accomplish something similar, but I would prefer to use a text field in my case.
EDIT: So I left out a big detail. I am firing an IBaction when pressing textField1 and 2. However, Lootsch's answer gave me an idea.
In the textField1/2Pressed IB action, I ran the textfield.enable:NO methods, then I re-enabled them when I fired a second action which submitted data to the textfields, such as below
- (IBAction)textField1Pressed:(id)sender {
self.textField.Enabled = NO;
}
- (IBAction)submitToTextField1:(id)sender {
self.textField.text = #"blah blah";
self.textField.Enabled = YES;
}
Albeit, this requires having two entering an exiting actions, but it worked for me. Also, I did not have to manipulate the textFieldShouldBeginEditing method with this solution.
You should disable these two textFields (in code or via IB) or you can disable the user interactions (different appearance, same function):
textField3.enabled = NO;
textField4.enabled = NO;
Or:
textField3.userInteractionEnabled = NO;
textField3.userInteractionEnabled = NO;
The second approach won't change the appearance of the UITextFields, while the first will indicate, that these TextFields are disabled.
something like should do
if (textField==textField1 || textField==textField2) [textField resignFirstResponder];
Please try this
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField==self.textField1 || textField==self.textField2)
{
return NO;
}
else
{
return YES;
}
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)mytextField
{
if((mytextField.tag == 104) || (mytextField.tag == 105) || (mytextField.tag == 106))
{
if(mytextField.tag == 104)
{
point = 50;
// if(textField1.tag == 4)
{
[self showDatePickerWithTitle:#"Select DOB"];
return NO;
}
//
}
}
else
{
retutn YES;
}
//you can also try this piece of code.With tag property of textfield.And make sure your tag is not zero,because the default tag is 0 for the main view.
I have 5 buttons in my xib, Button 1 to 4 is mapped to
-(IBAction)btn1to4:(UIButton *)sender;
Button 5 is mapped to
-(IBAction)btnFive:(id)sender;
Initially all the 4 buttons are hidden and only button 5 is visible, What I need is when I click on Button 5 all the 4 buttons should appear and when I click again on Button 5 they should disappear. For individual button I can write code in Button 5 as button1.hidden=NO, button2.hidden=NO and soon. But my buttons 1 to 4 are mapped to single btn1to4 method. How should I code in my btnFive method to hide/Unhide all 4 buttons at once?
Add buttons 1 through 4 to an IBOutletCollection in the interface builder. Add a property
#property (nonatomic, strong) IBOutletCollection(UIButton) NSArray *buttons1_4;
and drag buttons 1..4 there. Here is an answer explaining how to do it step-by-step.
Now you can operate all the buttons in that collection using a loop, rather than referencing them individually:
-(void)flipButtonsVisibility:(UIButton*)sender {
for (UIButton *btn in buttons1_4) {
btn.hidden = !btn.hidden;
}
}
Give tag of your button5 such like
button5.tag = 101;
In you button5's IBAction change id to UIButton * in parameter, such like
-(IBAction)btnFive:(UIButton *)sender
And Write following code
-(IBAction)btnFive:(UIButton *)sender
{
if(sender.tag == 101)
{
self.btn1.hidden = YES;
self.btn2.hidden = YES;
self.btn3.hidden = YES;
self.btn4.hidden = YES;
sender.tag = 102;
}
else
{
self.btn1.hidden = NO;
self.btn2.hidden = NO;
self.btn3.hidden = NO;
self.btn4.hidden = NO;
sender.tag = 101;
}
}
in your .h file
int a;
.m
-(void)viewDidLoad
{
a=0;
}
In your button click
-(IBAction)btnFive:(id)sender
{
if(a==0)
{
button1.hidden = YES;
button2.hidden = YES;
button3.hidden = YES;
button4.hidden = YES;
a = 1;
}
else
{
button1.hidden = NO;
button2.hidden = NO;
button3.hidden = NO;
button4.hidden = NO;
a = 0;
}
}
In your -(IBAction)btnFive:(id)sender, first check any one button (from 1-4) hidden property & do its opposite in condition. please find sample below -
-(IBAction)btnFive:(id)sender {
if(btn4.hidden==false){
btn1.hidden=true;
btn2.hidden=true;
btn3.hidden=true;
btn5.hidden=true;
}else{
btn1.hidden=false;
btn2.hidden=false;
btn3.hidden=false;
btn5.hidden=false;
}
}
try to write less number of line code and try to write effective lines.
If you need more help, please let me know. And if you find this answer suitable, Please vote me.
All the Best
I am trying to invoke -(BOOL) textFieldShouldClear:(UITextField *)textField when UITextField's clear button is tapped. I have already set my delegate and UITextField's other delegate's methods are being called correctly, except this one. Clear Button is set to "is always visible" in nib file.
EDIT
FYI I am showing FPPopover when textfield's text is changed. if I tap on clear button without showing popover, clear button works fine. But if I try to tap it when popover is being displayed, delegate method is not called.
Code Snippet
-(BOOL) textFieldShouldClear:(UITextField *)textField
{
return YES;
}
- (IBAction)didChangeScripText:(id)sender {
NSString *text = isPortrait ? symbolTextField.text : landsymbolTextfield.text;
if(scripList.count == 0)
{
if([Logs sharedManager].scripData.count > 0)
[self extractScrips];
else
return;
}
// SAFE_ARC_RELEASE(popover);
// popover=nil;
//the controller we want to present as a popover
if(controller == nil)
controller = [[scripComboViewController alloc] initWithStyle:UITableViewStylePlain];
if(controller.scripListFiltered.count > 0)
[controller.scripListFiltered removeAllObjects];
controller.delegate = self;
if(popover == nil){
popover = [[FPPopoverController alloc] initWithViewController:controller];
popover.tint = FPPopoverDefaultTint;
}
controller.scripListFiltered = [NSMutableArray arrayWithArray:[scripList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#",text]]];
NSLog(#"array is: %#",controller.scripListFiltered);
if(controller.scripListFiltered.count == 0)
{
[popover dismissPopoverAnimated:YES];
return;
}
//decide contentsize and arrow dir based on tableview height
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
popover.contentSize = CGSizeMake(300, 500);
}
else {
popover.contentSize = CGSizeMake(200, 200);
}
//sender is the uitextfield
float height = isPortrait ? portTable.frame.size.height : landTable.frame.size.height;
if(height > 0)
popover.arrowDirection = FPPopoverArrowDirectionDown;
else
popover.arrowDirection = FPPopoverArrowDirectionUp;
if(![popover isModalInPopover])
[popover presentPopoverFromView:sender];
[controller reloadTable];
}
What is going wrong? Can anyone tell me. Thanks.
Actually problem is due to FPPopover. When it receives touch event outside its view, it dismisses itself, and no interaction with outside controls is possible at that time. So if tap clear button, it will be used to dismiss the pop up and then I am able to use clear button. Thats all.