Custom and animated button in iOS Tab Bar - ios

I'm trying to get a custom tab bar for iPhone (iOS 6) and I've got to manage a central button that raises over the bar (based on code, https://github.com/tciuro/CustomTabBar) but now I have to face another feature: buttons must blink when clicked and glossy effect has to be removed. Any suggestion about the best way to get that? I'm still relatively new programming with iOS and its animations.
Thank you very much
What I already have so far:
In MBCenteredButtonVC (main entry in storyboard)
#import <UIKit/UIKit.h>
#interface MBCenteredButtonViewController : UITabBarController <UITabBarDelegate>
#property(nonatomic, weak) IBOutlet UIButton *centerButton;
#end
And its implementation:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tabBar setSelectedImageTintColor:[UIColor colorWithRed:171/225.0 green:233/255.0 blue:8/255.0 alpha:1]];
[self.tabBar setBackgroundImage:[UIImage imageNamed:#"bar-back.png"]];
// Do any additional setup after loading the view.
[self addCenterButtonWithImage:[UIImage imageNamed:#"button-rocketBg.png"] highlightImage:[UIImage imageNamed:#"button-rocketBg-active.png"] target:self action:#selector(buttonPressed:)];
}
Images for each item is defined within views properties using XCode. So, this way, I get a central button raised over the rest and I have changed the color for selected items but I need that they blink while content is being loading (it supposed that could take some time).
I feel that I have to implement this functionality when buttons are pressed:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
NSLog(#"Selected tab bar item: %i", item.tag);
}
}
but not sure if it the right way and how to do it exactly.

The easiest way to get started with animations on iOS is probably to use the UIView animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations method.
Documentation here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/doc/uid/TP40006816-CH3-SW111
Any values that are animatable that you change in that block will be animated.
Core Animation is extensive, and this barely scratches the surface of what can be done, but it might be enough to get you started.

Related

How to create a custom(self designed) uialertview in iOS

I stumbled across a lovely ui concept. I am wondering how could we create a "pop up" window like this in iOS(iPhone).
I have 3 questions:
How do we achieve that pop up style window?
What is the best approach to do that?
Thank you
EDIT: I would like to create a custom control like this.
It seems that the better way is to:
1- Create a class that inherits UIView and has a delegate class too.
your .h file should be something like this:
#import <UIKit/UIKit.h>
#class MYPopUpView;
//Your delegate class
#protocol PopUpViewDelegate <NSObject>
- (void) popUpView:(MYPopUpView *)popUpView clickedButtonAtIndex:(NSInteger) index;
#end
//Your view interface
#interface LIPopUpView : UIView{
NSObject<LIPopUpViewDelegate> *_delegate;
}
//Your methods and properties
#end
2- In the initializer of your .m file implement the UI of your PopUpView
3- For the circle you can use UILayer or even a custom button and when user clicks it fire your delegate methods.
4- Define a show methods with following code for showing the popUp:
- (void) show
{
UIWindow *window = [UIApplication sharedApplication].windows.lastObject;
[window addSubview:self];
[window bringSubviewToFront:self];
}
5- Fire the show method of you popUp object to show the popUp
6- For hiding it, define the close methods like below and fire it from the caller class.
- (void) close
{
[self removeFromSuperview];
}
Sounds to me the following will do:
Create a view controller whose view has sub-views look like the register window in the screenshot. For the non-rectangle shape, mask of the view layer may needs to be properly set.
Add the view of the view controller to the key window.

UISegmentedControl not firing UIControlEventValueChanged

I'm working on the IOS Programming: Big Nerd Ranch Guide Chapter 5 Silver Challenge and am wracking my brain trying to hook up the UISegmentedControl's change event.
Controller.m's initializer contains:
[segmentedControl addTarget:self
action:#selector(onChangeSegment:)
forControlEvents:UIControlEventValueChanged];
Controller.m also contains:
- (void) onChangeSegment:(id)sender
{
NSLog(#"Phew made it!");
}
Controller.h contains:
#interface
//...
- (void) onChangeSegment:(id)sender;
#end
All appears to be in place, however when the active segment is changed from the UI, onChangeSegment is never messaged. This is the case with either the simulator or my iPhone4S (IOS7 and XCode 5).
Any help or direction is appreciated. Please let me know if I can supply more details.
Please do a
NSLog(#"segmentedControl: %#", segmentedControl);
before your target action adding. Its possible you're trying to addTarget: to a nil object. If you're doing this via Interface Builder, the addTarget should be done in the -viewDidLoad: method.
What I did in a sample app was:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.segmentedControl addTarget:self action:#selector(change:) forControlEvents:UIControlEventValueChanged];
}
-(void)change:(UISegmentedControl *)control{
NSLog(#"changed!");
}
The Segmented Control was created using IB and linked to the view controller's header.
You said:
Controller.m's initializer contains:
In initializer you don't have IBOutlets from XIB so segmentedControl == nil at that time and method call does nothing. Views are usually configured in -viewDidLoad method where IBOutlets are guaranteed to be loaded from xib. So simply move
[segmentedControl addTarget:self
action:#selector(onChangeSegment:)
forControlEvents:UIControlEventValueChanged];
to -viewDidLoad method. Other things seem to be ok.

UISearch bar not calling searchBarTextDidBeginEditing

I have a simple view controller with a uisearchbar and a uitable.
My problem is that when search bar is tapped I see delegate function searchBarShouldBeginEditing being called but not searchBarTextDidBeginEditing(and because of that keyboard is not opened and search is not editable)
I tried to implement delegate function searchBarShouldBeginEditing returning YES, set searchbar as first responder, but no way I get searchBarTextDidBeginEditing called...
Any idea what could be happening??
Some code:
controller.h
#interface ViewController : UIViewController <UISearchBarDelegate>
{
UISearchBar * searchbar;
}
#property (nonatomic, retain) IBOutlet UISearchBar* searchbar;
#end
controller.m
#synthesize searchbar;
- (BOOL)respondsToSelector:(SEL)sel {
NSLog(#"Queried about %#", NSStringFromSelector(sel));
return [super respondsToSelector:sel];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
NSLog(#"searchBarShouldBeginEditing -Are we getting here??");
return YES;
}
-(void) searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
NSLog(#"searchBarTextDidBeginEditing -Are we getting here??");
}
Of cousrse my class have plenty more code (that surely is affecting somehow searchbar) but if someone has got similar problems with searchbar it would be very apreciated its response ;)
I tryed to make simple application with only searchbar and obviously it works...
EDITING:
Testing a little bit I discovered that it is not something related with uisearchbar as I added a TextField getting same result (just textFieldShouldStartEditing delegate function being called)
Application has all view controllers inside a UITabBar cotroller, but I do not think this can cause all this mess...
EDITING2:
Really strange behaviour: Setting IBAction function to TouchDown event of a UITextfield works perfectly but setting IBAction function to EditingDidBegin never gets fired...
Why this event could not be called??
did you set the delegate property?
searchbar.delegate = self;
Maybe you somewhere call [searchbar resignFirstResponder]. It was the case in my similar problem.
I had this problem when I was converting from a standalone UISearchBar to a searchBar integrated into the UINavigationBar.
In converting my code, I was still allocating the UISearchBar and setting the delegate for that. What I should have been doing was configuring the searchBar that comes as part of of the UISearchController, and setting the delegate of that,
self.searchController.searchBar.delegate = self;
Once I did that, my delegate methods started firing!

Delegate for UITextField not working...Return button not responding

I've just started with xcode and objective-c and did some very basic apps, but what i'm having problem with is very basic this. the keyboard return button not hiding the keyboard.
I've searched the internet for the solution and all they say is to connect delegate to the file's owner and add the function and it should work, i did that and nothing is working.
I have an ok button and it is working and also clicking on any free space on the screen is working, just the return button....
I am using the simulator, not testing on iphone yet. (xcode 3.2.5 64 bit with the 4.2 simulator).
This is the line of code that should connect the delegate to every textFiled.
1. i've tried already to return both YES and NO, didn't work.
2. i've tried both a specific object name for the textField and this general way, didn't work.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
In the: basic view controller connection -> connections -> outlets, i have the: delegate -- File's Owner. and in the file's owner in referencing outlets there is: delegate - Round style text.....
EDIT - i forgot to mention before, i've check and the method isn't being called!!!
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(#"Working!!!");
[textField resignFirstResponder];
return YES;
}
what should i do to make it happen? that is why people say to connect the delegate, but in my case it is connected and not triggering the function...i know it is kind of dumb question but for a nobie like me the solution is not obvious...
OK, another Edit - with all my code: just can't understand what to do....
This is: basicViewController.h:
#import <UIKit/UIKit.h>
#interface basicViewController : <#superclass#> <UITextFieldDelegate>
#interface basicViewController : UIViewController <UITextFieldDelegate> {
//every object that we want to interact with (like text field or lable) is call an outlet!!!!
//here we define the outlets for our program
IBOutlet UITextField *txtName;
IBOutlet UILabel *lblMessage;
}
//here are the getters and setter for our outlets
#property (nonatomic, retain) IBOutlet UITextField *txtName;
#property (nonatomic, retain) IBOutlet UILabel *lblMessage;
//method decleration for the OK button action
- (IBAction) doSomething;
//method for hiding the keyboard when clicking on empty area in the app
//we will put an invisible button on all area and clicking on it will make keyboard disapear
- (IBAction) makeKeyboardGoAway;
#end
This is basicViewController.m:
#import "basicViewController.h"
#implementation basicViewController
//synthesizeing the objects that we made' this will create the getter and setters automaticly
#synthesize txtName;
#synthesize lblMessage;
- (IBAction) doSomething{
// makeing keyboard disapear when pressing ok button (doing that form the text field)
//when pressing the OK button, the keyboard will disapear and when clicking in the text field it will show again
[txtName resignFirstResponder];
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %#",txtName.text];
//the objective-c way for setting the test in the text field
[lblMessage setText:msg];
//the regular object oriented way
//lblMessage.text = msg;
[msg release];
}
- (IBAction) makeKeyboardGoAway{
[txtName resignFirstResponder];
}
//when clicking the return button in the keybaord
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(#"Working!!!");
[textField resignFirstResponder];
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Maybe now i am more clear, sorry i didn't do it before.
Any one has an idea what am i doing wrong? it should be pretty strait forward.....
EDIT - Adding an image of all the elements, i hope that will help to help me :-)
10x a lot for every one that is trying to help....i really like this framework, it is so great after c++ and java, python and many other...and i am working with a book, but it is for ios 3.1, maybe that is the problem.....
Firstly you should check if textFieldShouldReturn: is actually being called by adding an NSLog statement or breakpoint at the beginning of the method.
Once that's out of the way, try an manually declare that your view controller conforms to <UITextFieldDelegate> protocol in your interface file:
#interface YourClass : ... <UITextFieldDelegate>
Also declare a property & outlet for your UITextField, make the appropriate connections in IB and manually declare self as the UITextField delegate with:
self.yourUITextFieldObject.delegate = self;
Once that's done see if your method above is now being called and make sure you return YES.
Just write one line in the
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
}
before return YES;
the final version will be as given below:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(#"%#",textField.text);
}
You need to assign the delegate of the textfields to your file owner. The textfields are sending the message, but doesn't have a delegate to respond to it.
Use the interface builder to do that.
You have to implement this method..
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Like Rog said, don't forget to register the textfield to the delegate, you can do this manually as he said but in Storyboard you can just control drag from all of your textfields to the view controller and register the delegate (choose delegate). Only the textfields that are registered can make use of all those methods.
So this line is important:
self.yourUITextFieldObject.delegate = self;
Or even more easy these days is to just use the storyboard:
textfield is in a subview? in this case, make sure textfield have as delegate the FileOwner.
put a log at the
- (IBAction) makeKeyboardGoAway
function. I think its this method everytime anything is tapped on the screen. In that case, you will need to send the touch event to the text field. Not sure how this is done but that should do it.
Else try removing the which takes care of tap(click) all over the view and try to do what you are doing.
Most likely the problem is that your actual view controller in the running application is not a "basicViewController" but a UIViewController that does not implement the UITextFieldDelegate-protocol.
What you've done in the interface builder by selecting your class "basicViewController" as the FilesOwner is just declaring the FilesOwner-object in your running application to be of type basicViewController; the actual object is not instantiated by this declaration and in your case it is not in the xib / nib.
Some other part of your code actually instantiates a view controller object and loads the xib / nib file. At that place, I guess your code is instantiating a UIViewController (typically by auto-generated code) and not an instance of your basicViewController; you simply have to change the class there.
Furthermore, this error often happens when using a UINavigationController or UITabBarController in the Interface Builder that is (should be) configured to instantiate and load other custom views. If you use such a higher-level controller, double-check that it is actually configured to use your basicViewController, not UIViewController when loading your view from the xib / nib.
Hope, that solves the issue!
Can you try this..
#interface ClassName : SuperClass < UITextFieldDelegate >
Use like this...
textfield.delegate=self;
and use the UITextFieldDelegate in .h class
You can always dismiss the keyboard when you don’t even know which view the text field is in by using:
Objective-C:
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder)
to:nil
from:nil
forEvent:nil];
Swift:
UIApplication.sharedApplication().sendAction("resignFirstResponder",
to:nil,
from:nil,
forEvent:nil)

UISearchDisplayController Without Dimming?

I am writing a SplitView iPad app. Inside the DetailViewController, there's a little view that contains a UITableView and a UISearchBar and its controller. This view does not represent the whole screen space reserved for the DetailViewController. Actually, it uses just half of it. There's an UIImageView on the other half.
And this is where trouble comes in: every time I use the search bar, the displaycontroller (I assume) dims everything present inside the DetailViewController, including the image view. That is not consistent with what someone would expect when running the app. Is there any way to set the frame to be dimmed? Or at least disable dimming for good?
Thanks in advance.
You are correct that it is the UISearchDisplayController that is managing the "dimming" effect that you're seeing.
What the UISearchDisplayController is doing is adding a UIControl as a subview to the view of the searchContentsController (a property of UISearchDisplayController), which is likely your detail-view controller. This UIControl is just an alpha'd view with a gray background. It seems to have a touch-up-inside event handler that ends searching when tapped.
To constrain the dimming effect to your sub-view of the detail-view, you need to do three things. (I'm assuming your detail-view-controller is defined via a xib. If not, these steps can be done in code too.)
1) add a new UIViewController to your detail-view-controller xib. Attach this new view-controller to an IBOutlet of your detail-view-controller. In my example I call this "_searchAreaViewController". This is important, even if you wont ever access the view controller (but remember, you'll have to release it at some point)
#interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate, UITableViewDelegate, UITableViewDataSource> {
UIPopoverController *popoverController;
UIToolbar *toolbar;
id detailItem;
UILabel *detailDescriptionLabel;
IBOutlet UIViewController* _searchAreaViewController;
}
2) make the containing view for your search area the view of this new view-controller. To do this, use Interface Builder to set a new referencing outlet for this view by dragging the outlet to the searchAreaViewController and selecting the "view" outlet. You must have a containing view - it should be a subview of your detail-view, and it should contain the UISearchBar and likely your UITableView.
3) make the searchContentsController property of the UISearchDisplayController refer to this new view controller instead of the detail-view-controller. This can only be done via Interface Builder as the property is read-only (IB has some magic to make this work?) If you need to do this step via code you'll have to subclass the UISearchDisplayController and return the correct value from a property override of "searchContentsController".
I made a sample app to demonstrate this and the only line of code I had to add to the SplitView template was the one listed in step 1 above. Everything else was just adding the views/controllers and connecting them properly in IB.
good luck!
iOS 8+
[[UIView appearanceWhenContainedInInstancesOfClasses:#[NSClassFromString(#"UISearchDisplayControllerContainerView")]] setHidden:YES];
iOS 7
[View appearanceWhenContainedIn:NSClassFromString(#"UISearchDisplayControllerContainerView"), nil] setHidden:YES];
I know, that UISearchDisplayController is deprecated for now, but if you still need to use it, you can solve your issue with one line of code perfectly. Add it to viewDidLoad method.
Could you clarify what you mean by "use the search bar" and "dims everything present"? I interpret what you wrote in such a way that the keyboard pops up when you are about to enter text in the text field of the search bar. And that at this point the detail view is dimmed out, preventing user interaction.
The cause is that the search bar implements a modal dialog which prevents user interaction with the view as long as the keyboard is shown. Unfortunately, there doesn't seem to be any way to configure the search bar to prevent this behavior. On the other hand I am not sure that the user won't expect this behavior since search bars are modal consistently and behave like this in general under iOS.
I have tried two work-arounds:
1.) There is a property of the UIViewController called modalPresentationStyle which produces exactly the behavior you describe if it has the value UIModalPresentationFormSheet ("All uncovered areas are dimmed to prevent the user from interacting with them.", see the Apple documentation). But setting this property to a different values does not change the result (at least for me it didn't work).
2.) You would need to write your own non-modal search bar replacement since a standard UITextField is non-modal and thus does not dim out any other UI elements. This approach works, but you might need a little more work to make it look like a "regular" search bar. But, again, since this search bar behaves differently from the modal normal search bars in iOS this might not really be what the users expect.
I know I am late and this is a horrible idea here, but 'setHidden:No' did not work for me.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
BOOL hasBeenremoved = NO;
hasBeenremoved = [[[[NSThread mainThread] threadDictionary] objectForKey:#"hasBeenremoved"] boolValue];
if (hasBeenremoved)
{
UIView* dimmingView = nil;
dimmingView = [[[NSThread mainThread] threadDictionary] objectForKey:#"dimmingView"];
UIView* dimmingViewSuperView = nil;
dimmingViewSuperView = [[[NSThread mainThread] threadDictionary] objectForKey:#"dimmingViewSuperView"];
[dimmingViewSuperView addSubview:dimmingView];
[[[NSThread mainThread] threadDictionary] setObject:#NO forKey:#"hasBeenremoved"];
}
if ([searchText length] == 0 || [searchText isEqualToString:#""] )
{
[searchBar becomeFirstResponder];
[[[self primarySearchDisplayController] searchResultsTableView] reloadData];
[[[self primarySearchDisplayController] searchResultsTableView] setHidden:NO];
for( UIView *subview in self.view.subviews )
{
if([subview isMemberOfClass:[UIControl class]] ||
([[[subview class] description] isEqualToString:#"UISearchDisplayControllerContainerView"]))
{
for(UIView *subView2 in subview.subviews)
{
for(UIView *subView3 in subView2.subviews)
{
if (subView3.alpha < 1)
{
if ([[[subView3 class] description] isEqualToString:#"_UISearchDisplayControllerDimmingView"])
{
[[[NSThread mainThread] threadDictionary] setObject:subView3 forKey:#"dimmingView"];
[[[NSThread mainThread] threadDictionary] setObject:subView3.superview forKey:#"dimmingViewSuperView"];
[[[NSThread mainThread] threadDictionary] setObject:#YES forKey:#"hasBeenremoved"];
[subView3 removeFromSuperview];
}
}
}
}
}
}
}
}

Resources