I have a UITextField for the UISearchBar which this was working until iOS 7 upgrade and now it fails at this line: UITextField *textfield=(UITextField*)[[searchBar subviews] objectAtIndex:1];
any idea how to fix this? thanks
// search bar
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 190.0, 44.0)];
searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
UIView *searchBarView = [[UIView alloc] initWithFrame:CGRectMake(90.0, 0.0, 230.0, 44.0)];
searchBarView.autoresizingMask = 0;
searchBar.delegate = self;
searchBar.layer.borderColor=[UIColor whiteColor].CGColor;
UITextField *textfield=(UITextField*)[[searchBar subviews] objectAtIndex:1];
[searchBarView addSubview:searchBar];
self.navigationItem.titleView = searchBarView;
try this , it's work in Both IOS6 and IOS7+ and safe approch
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setFont:[UIFont fontWithName:#"ArialMT" size:10]];
It's not a good idea to assume that second searchBar's subview will be UITextField.
I printed out subviews for UISearchBar, that's what I got on iOS 7:
<__NSArrayM 0x17d141f0>(
<UIView: 0x17d34f40; frame = (0 0; 320 44); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x17d34fa0>>
)
Only one subview, so your ... objectAtIndex:1] will definitely crash.
You can use the following category for UIView to find UITextField in your searchBar:
#interface UIView(Utils)
-(UIView*)findSubviewRecursivelyOfClass:(Class)subviewClass;
#end
#implementation UIView(Utils)
-(UIView*)findSubviewRecursivelyOfClass:(Class)subviewClass
{
if( [self isKindOfClass:subviewClass] ) {
return self;
} else {
for( UIView* child in self.subviews ) {
UIView* result = [child findSubviewRecursivelyOfClass:subviewClass];
if( result ) {
return result;
}
}
return nil;
}
}
#end
Try this one for iOS7.
TESTED
for (id object in [searchBar subviews])
{
for (id subObject in [object subviews])
{
if ([subObject isKindOfClass:[UITextField class]])
{
UITextField *textfield=(UITextField*)subObject;
}
}
}
iOS6
for (id object in [searchBar subviews]) {
if ([object isKindOfClass:[UITextField class]]) {
UITextField *textfield=(UITextField*)object;
}
}
How about a recursive method that can trick to work in any version
UITextField *searchBarTextField = [self findTextFieldFromControl:self.placeSearchBar];
- (UITextField *) findTextFieldFromControl:(UIView *) view
{
for (UIView *subview in view.subviews)
{
if ([subview isKindOfClass:[UITextField class]])
{
return (UITextField *)subview;
}
else if ([subview.subviews count] > 0)
{
return [self findTextFieldFromControl:subview];
}
}
return nil;
}
Related
I'm in the process of making a tutorial, and I'm trying to emulate the style of Path's tutorial like so:
http://www.appcoda.com/wp-content/uploads/2013/06/UIPageViewController-Tutorial-Screen.jpg
My issue is that if set the delegate method as so:
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
return 5;
}
Then I get this stupid black bar under the dots:
http://i.stack.imgur.com/pUEdh.png
Is there a way to make this bar translucent in a way thats similar to setting a UINavigationBar to translucent?
It is very easy to make it work. You just only have to make the pageviewcontroller taller, and place a PageControl into the XIB file.
The trick is put the PageControl in the foreground (and all the other common controls) at the beginning, and update the content of the PageControl with the PageViewController. Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageController.dataSource = self;
// We need to cover all the control by making the frame taller (+ 37)
[[self.pageController view] setFrame:CGRectMake(0, 0, [[self view] bounds].size.width, [[self view] bounds].size.height + 37)];
TutorialPageViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
// Bring the common controls to the foreground (they were hidden since the frame is taller)
[self.view bringSubviewToFront:self.pcDots];
[self.view bringSubviewToFront:self.btnSkip];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [(TutorialPageViewController *)viewController index];
[self.pcDots setCurrentPage:index];
if (index == 0) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [(TutorialPageViewController *)viewController index];
[self.pcDots setCurrentPage:index];
index++;
if (index == 3) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (TutorialPageViewController *)viewControllerAtIndex:(NSUInteger)index {
TutorialPageViewController *childViewController = [[TutorialPageViewController alloc] initWithNibName:#"TutorialPageViewController" bundle:nil];
childViewController.index = index;
return childViewController;
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
NSInteger tutorialSteps = 3;
[self.pcDots setNumberOfPages:tutorialSteps];
return tutorialSteps;
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return 0;
}
The same effect can be achieved simply by subclassing UIPageViewController and overriding viewDidLayoutSubviews as follows:
-(void)viewDidLayoutSubviews {
UIView* v = self.view;
NSArray* subviews = v.subviews;
// Confirm that the view has the exact expected structure.
// If you add any custom subviews, you will want to remove this check.
if( [subviews count] == 2 ) {
UIScrollView* sv = nil;
UIPageControl* pc = nil;
for( UIView* t in subviews ) {
if( [t isKindOfClass:[UIScrollView class]] ) {
sv = (UIScrollView*)t;
} else if( [t isKindOfClass:[UIPageControl class]] ) {
pc = (UIPageControl*)t;
}
}
if( sv != nil && pc != nil ) {
// expand scroll view to fit entire view
sv.frame = v.bounds;
// put page control in front
[v bringSubviewToFront:pc];
}
}
[super viewDidLayoutSubviews];
}
Then there is no need to maintain a separate UIPageControl and such.
Swift 3 snippet
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let scrollView = view.subviews.filter({ $0 is UIScrollView }).first,
let pageControl = view.subviews.filter({ $0 is UIPageControl }).first {
scrollView.frame = view.bounds
view.bringSubview(toFront:pageControl)
}
}
Here's a conversion of Zerotool's solution into Swift 2.1, though there's probably a more elegant way to write it:
override func viewDidLayoutSubviews() {
var scrollView: UIScrollView?
var pageControl: UIPageControl?
// If you add any custom subviews, you will want to remove this check.
if (self.view.subviews.count == 2) {
for view in self.view.subviews {
if (view.isKindOfClass(UIScrollView)) {
scrollView = view as? UIScrollView
} else if (view.isKindOfClass(UIPageControl)) {
pageControl = view as? UIPageControl
}
}
}
if let scrollView = scrollView {
if let pageControl = pageControl {
scrollView.frame = self.view.bounds
self.view.bringSubviewToFront(pageControl)
}
}
super.viewDidLayoutSubviews()
}
I don't think you can change the behavior of UIPageViewController, so it seems likely that the Path app uses its own view controller. You can do the same: create your own container view controller that uses a UIPageControl to indicate the current page.
You can simply adjust the alpha of the UIPageViewController's UIPageControl.
First, you should retrieve it from the UIPageViewController like so:
- (UIPageControl *)getPageControlForPageViewController:(UIPageViewController *)pageViewController {
for (UIView *subview in self.pageViewController.view.subviews) {
if ([subview isKindOfClass:[UIPageControl class]]) {
return (UIPageControl *) subview;
}
}
return nil;
}
Next, make use of the function. I've made a property on my ViewController called childPageControl. Give it the UIPageViewController's UIPageControl:
self.childPageControl = [self getPageControlForPageViewController:self.pageViewController];
Next, you can adjust the alpha to give a translucent effect:
self.childPageControl.alpha = .5;
You're very limited in what you can do to affect the UIPageViewController's UIPageControl, but you can at least achieve this with little effort.
Small hack I found today..
Please see the code below.
self.pageController.dataSource = self;
CGRect rect = [self.view bounds];
rect.size.height+=37;
[[self.pageController view] setFrame:rect];
NSArray *subviews = self.pageController.view.subviews;
UIPageControl *thisControl = nil;
for (int i=0; i<[subviews count]; i++) {
if ([[subviews objectAtIndex:i] isKindOfClass:[UIPageControl class]]) {
thisControl = (UIPageControl *)[subviews objectAtIndex:i];
}
}
UIView *tempview = [[UIView alloc] initWithFrame:CGRectMake(0, -30, 320, 40)];
[tempview addSubview:thisControl];
thisControl.pageIndicatorTintColor = [UIColor lightGrayColor];
thisControl.currentPageIndicatorTintColor = [UIColor greenColor];
[self.view addSubview:tempview];
this code is in Swift
Add following in your UIPageViewController
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews {
if view.isKindOfClass(UIScrollView) {
view.frame = UIScreen.mainScreen().bounds
} else if view.isKindOfClass(UIPageControl) {
view.backgroundColor = UIColor.clearColor()
}
}
}
I wanted to do a similar effect in the app I was working on - I used a UIPageViewController with a separate UIPageControl.
This lets you place the UIPageControl anywhere you'd like in the view, including over the top of the UIPageViewController, and you keep its active page dot up to date via the UIPageViewController delegate method:
- (void)pageViewController:(UIPageViewController *)pageViewController
didFinishAnimating:(BOOL)finished
previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers
transitionCompleted:(BOOL)completed {
if (completed) {
self.pageControl.currentPage = [self.pageViewControllers indexOfObject:pageViewController.viewControllers.firstObject];
}
}
No need to traverse the subview hierarchy trying to find the internal UIPageViewController page control, nor having to resize the contents of the internal scrollview.
Hope this helps.
I solve using this code:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.namesImage = #[#"page1.png", #"page2.png", #"page3.png", #"page4.png"];
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.pageViewController.dataSource = self;
TutorialContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
[[UIPageControl appearance] setPageIndicatorTintColor:[UIColor grayColor]];
[[UIPageControl appearance] setCurrentPageIndicatorTintColor:[UIColor whiteColor]];
[[UIPageControl appearance] setBackgroundColor: [[UIColor blackColor] colorWithAlphaComponent:0.1f]];
[[UIPageControl appearance] setOpaque:YES];
}
Swift 5.2
you can use this code for your requirment
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let myScrollView = view.subviews.filter({ $0 is UIScrollView }).first,
let myPageControl = view.subviews.filter({ $0 is UIPageControl }).first {
myScrollView.frame = view.bounds
view.bringSubviewToFront(myPageControl)
}
}
I found an other workarround that fits me better.
I reuse the code given by zerotool to get the UIPageControl (var called pageControl) and the UIScrollView (var called pageView) used by the UIPageViewController.
Once that done in the viewDidLoad, I just prevent clip subview of pageView and let the content spread more to be beneath the UIPageControl.
The pageControl is beneath the pageView so we have to manually make it come in front.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
if(
[[[self view] subviews] count] == 2
)
{
UIScrollView* pageView = nil;
UIPageControl* pageControl = nil;
UIView* selfView = self.view;
NSArray* subviews = selfView.subviews;
for( NSInteger i = 0 ; i < subviews.count && ( pageView == nil || pageControl == nil ) ; i++ )
{
UIView* t = subviews[i];
if( [t isKindOfClass:[UIScrollView class]] )
{
pageView = (UIScrollView*)t;
}
else if( [t isKindOfClass:[UIPageControl class]] )
{
pageControl = (UIPageControl*)t;
}
}
if( pageView != nil && pageControl != nil )
{
[pageView setClipsToBounds:NO];
[selfView bringSubviewToFront:pageControl];
}
}
}
Once I get my pageView covering the space occupied by the pageControl but under the pageControl, I just have to adjust the nib file use for each viewController displayed as page :
base view should not clip
the first and only subview :
should have constraint to set bottom to -37 (or more if you need but 37 is the size of the pageControl) from bottom of superview
should clip content
I am looking for 3 hours now on Google how to remove the tableview and show an image when the tableview is empty (have no more rows). Does someone know this? I know it's possible, because I saw it on many apps.
What I could find was:
// Check if table view has any cells
int sections = [self.tableView numberOfSections];
BOOL hasRows = NO;
for (int i = 0; i < sections; i++)
hasRows = ([self.tableView numberOfRowsInSection:i] > 0) ? YES : NO;
if (sections == 0 || hasRows == NO)
{
UIImage *image = [UIImage imageNamed:#"test.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// Add image view on top of table view
[self.tableView addSubview:imageView];
// Set the background view of the table view
self.tableView.backgroundView = imageView;
}
where to put this?
Thanks!
If your using Storyboard just put your view behind your UITableView
If your array of data is empty when creating it, simply hide your UITableView to show the "empty table" view behind it.
[tableView setHidden:YES];
Please refer to:
http://www.unknownerror.org/Problem/index/905493327/how-do-i-display-a-placeholder-image-when-my-uitableview-has-no-data-yet/
Thanks to Cocoanut and Thomas:
#interface MyTableViewController : UITableViewController
{
BOOL hasAppeared;
BOOL scrollWasEnabled;
UIView *emptyOverlay;
}
- (void) reloadData;
- (void) checkEmpty;
#end
#implementation MyTableViewController
- (void)viewWillAppear:(BOOL)animated
{
[self reloadData];
[super viewWillAppear: animated];
}
- (void)viewDidAppear:(BOOL)animated
{
hasAppeared = YES;
[super viewDidAppear: animated];
[self checkEmpty];
}
- (void)viewDidUnload
{
if (emptyOverlay)
{
self.tableView.scrollEnabled = scrollWasEnabled;
[emptyOverlay removeFromSuperview];
emptyOverlay = nil;
}
}
- (UIView *)makeEmptyOverlayView
{
UIView *emptyView = [[[NSBundle mainBundle] loadNibNamed:#"myEmptyView" owner:self options:nil] objectAtIndex:0];
return emptyView;
}
- (void) reloadData
{
[self.tableView reloadData];
if (hasAppeared &&
[self respondsToSelector: #selector(makeEmptyOverlayView)])
[self checkEmpty];
}
- (void) checkEmpty
{
BOOL isEmpty = YES;
id<UITableViewDataSource> src = self.tableView.dataSource;
NSInteger sections(1);
if ([src respondsToSelector: #selector(numberOfSectionsInTableView:)])
sections = [src numberOfSectionsInTableView: self.tableView];
for (int i = 0; i < sections; ++i)
{
NSInteger rows = [src tableView: self.tableView numberOfRowsInSection: i];
if (rows)
isEmpty = NO;
}
if (!isEmpty != !emptyOverlay)
{
if (isEmpty)
{
scrollWasEnabled = self.tableView.scrollEnabled;
self.tableView.scrollEnabled = NO;
emptyOverlay = [self makeEmptyOverlayView];
[self.tableView addSubview: emptyOverlay];
}
else
{
self.tableView.scrollEnabled = scrollWasEnabled;
[emptyOverlay removeFromSuperview];
emptyOverlay = nil;
}
}
else if (isEmpty)
{
// Make sure it is still above all siblings.
[emptyOverlay removeFromSuperview];
[self.tableView addSubview: emptyOverlay];
}
}
#end
UITableView is a (non direct) subclass of UIView, so what you want to do is easy.
Say that you have this table view as subview of your view controller's view. This case you just create another view with the same frame as the table view, then you remove your table view from the superview, and add the newly created view as subview of your view controller's view. So simply:
UIImageView* view= [[UIImageView alloc] initWithImage: yourImage];
view.frame= tableView.frame;
[tableView removeFromSuperview];
[self.view addSubview: view];
Put it on - (void)viewDidAppear. Good luck ;)
I need to know how to stop scrolling in a UIwebview in xcode 4?
[[[webView subviews] lastobject] setScrollingEnabled:NO];
The above code does not work because "NSarray" for instance message does not declare a method with selector 'lastobject'. Why is this or is there new code I am unaware of to disable scrolling? Thanks.
UIView* row = nil;
for(row in webView.subviews){
if([row isKindOfClass:[UIScrollView class] ]){
UIScrollView* scrollRow = (UIScrollView*) row;
scrollRow.scrollEnabled = NO;
scrollRow.bounces = NO;
scrollRow.backgroundColor=[UIColor clearColor];
}
}
your code is trying to make assumptions about the order of the subviews that Apple is defining..
Note that with iOS 5 you have direct access to the scroll view.
So if you wanted to maintain compatibility you could do this:
UIScrollView *scrollView = nil;
if ([webView respondsToSelector:#selector(scrollView)]) { //iOS 5+
scrollView = webView.scrollView;
} else { //iOS 4-
for(UIView *view in webView.subviews){
if([view isKindOfClass:[UIScrollView class] ]){
scrollView = (UIScrollView *) view;
break;
}
}
}
scrollView.scrollEnabled = NO;
scrollView.bounces = NO;
scrollView.backgroundColor=[UIColor clearColor];
Simply add this line to viewDidLoad:
myWebView.scrollView.scrollEnabled = NO;
I would set the webview's UserInteractionEnabled property to NO so that it cannot be scrolled.
In my application I have to add a search bar at the head of the tableview. I am able to add the searchbar but problem is without adding default search bar of ios can i add my customize search bar?? I am giving an image to see what types of search bar will be there...
you can subclass the UISearchBar and override the layoutSubviews method :
- (void)layoutSubviews {
UITextField *searchField;
NSUInteger numViews = [self.subviews count];
for(int i = 0; i < numViews; i++) {
if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]]) { //conform?
searchField = [self.subviews objectAtIndex:i];
}
}
if(!(searchField == nil)) {
searchField.textColor = [UIColor whiteColor];
[searchField setBackground: [UIImage imageNamed:#"yourImage.png"] ];
[searchField setBorderStyle:UITextBorderStyleNone];
}
[super layoutSubviews];
}
Also you can :
//to clear searchbar backgraound
- (void) clearSearchBarBg
{
for (UIView *subview in theSearchBar.subviews)
{
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
[subview removeFromSuperview];
break;
}
}
}
//display showSearchButtonInitially in a keyboard
- (void)showSearchButtonInitially
{
UIView * subview;
NSArray * subviews = [theSearchBar subviews];
for(subview in subviews)
{
if( [subview isKindOfClass:[UITextField class]] )
{
NSLog(#"setEnablesReturnKeyAutomatically");
[((UITextField*)subview) setEnablesReturnKeyAutomatically:NO];
((UITextField*)subview).delegate=self;
[((UITextField*)subview) setEnabled:TRUE];
((UITextField*)subview).borderStyle = UITextBorderStyleNone;
break;
}
}
}
Look for Apple DOC for UISearchBar
You have bunch of methods there to get whatever you want
You can get UITextView Inside the search bar by
UITextField *textField = [searchBar.subviews objectAtIndex:2];
if ([textField isKindOfClass:[UITextField class]]) {
//Do your customization
}
Again look for AppleDoc for UITextField. You have bunch of methods for that also.
Yeah definitely. You can make your custom search bar (which is a sub-class of UIView) and add it as subview to the tableHeaderView.
[[searchBarDesign.subviews objectAtIndex:0] removeFromSuperview];
here searchBarDesign is my searchBar name.
I think it's better just set all properties of UISearchBar when it is loaded.
#interface MySearchBar : UISearchBar
#end
#implementation MySearchBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self myInitialize];
}
return self;
}
-(void)awakeFromNib
{
[super awakeFromNib];
[self myInitialize];
}
-(void)myInitialize
{
self.backgroundImage = [UIImage imageNamed:#"image.png"];
for (UIView* subview in self.subviews) {
if ([subview isKindOfClass:[UITextField class]]) {
//customize text field
UITextField* textfield = (UITextField*) subview;
}
}
}
#end
I subclassed UISearchBar in order to set custom image to search results button the following way (.m file):
#import "CustomUISearchBar.h"
#define RGB(r, g, b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
#define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]
#implementation GipUISearchBar
- (void)layoutSubviews
{
UITextField *searchField = nil;
UIView *backGround = nil;
UIButton *cancelButton = nil;
NSUInteger numViews = [self.subviews count];
for(int i = 0; i < numViews; i++)
{
if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]])
{
searchField = [self.subviews objectAtIndex:i];
}
else if ([[self.subviews objectAtIndex:i] isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
backGround = [self.subviews objectAtIndex:i];
}
else if ([[self.subviews objectAtIndex:i] isKindOfClass:[UIButton class]])
{
cancelButton = [self.subviews objectAtIndex:i]; [cancelButton setTintColor:RGB(22.0,38.0,111.0)];
}
}
if(!(searchField == nil))
{
searchField.layer.cornerRadius=15.0f;
searchField.layer.masksToBounds=YES;
searchField.layer.borderColor = [RGB(26.0,141.0,223.0)CGColor];
searchField.layer.borderWidth = 2.0f;
UIImage *glassImage = [UIImage imageNamed: #"search_icon.png"];
UIImageView *iView = [[UIImageView alloc] initWithImage:glassImage];
searchField.leftView = iView;
[iView release];
UIImage *historyImage = [UIImage imageNamed:#"history_button.png"];
UIButton *historyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[historyButton setBackgroundImage:historyImage forState:UIControlStateNormal];
[historyButton setBackgroundImage:historyImage forState:UIControlStateSelected];
[historyButton setBackgroundImage:historyImage forState:UIControlStateDisabled];
[historyButton setBackgroundImage:historyImage forState:UIControlStateHighlighted];
historyButton.frame = CGRectMake(0,
0,
historyImage.size.width-3,
historyImage.size.height-3);
historyButton.layer.borderColor = [RGBA(0.0,0.0,0.0,0.0)CGColor];
historyButton.layer.borderWidth = 0.0f;
searchField.rightView = historyButton;
}
if (!(backGround == nil))
[backGround removeFromSuperview];
[super layoutSubviews];
}
The problem is when i touch inside search bar and it resizes i see this button being moved from left to right. How can i disable this behaviour?
try commenting below lines.
[super layoutSubviews];
Because it seems that you are overriding layout of UISearchBar by inheriting it.