Customize searchbar searchIcon - ios

I am customizing my search bar with this but it is not showing any image. It remove its default image as well.
UITextField *searchField = nil;
for (UIView *subview in [[workLocationSearchBar.subviews lastObject] subviews]) {
NSLog(#"hey");
if ([subview isKindOfClass:[UITextField class]]) {
searchField = (UITextField *)subview;
NSLog(#"inside");
break;
}
}
if (searchField) {
UIView *searchIcon = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"circle.png"]];
if ([searchIcon isKindOfClass:[UIImageView class]]) {
}
NSLog(#"aye");
searchField.rightView = searchIcon;
searchField.leftView=searchIcon;
}

Try This:
[workLocationSearchBar setImage:[UIImage imageNamed:#"IMAGE_NAME"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];

Related

Objective-c App crashing in iOS 13(Search bar issue)

Please someone help me I am not familiar with Objective-c. App is crashing in iOS 13
found the following error in console
* Terminating app due to uncaught exception 'NSGenericException', reason: 'Missing or detached view for search bar layout. The application must not remove > from the hierarchy.'
Search bar code
UIImageView *searchBackView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 45, 320, 30)];
searchBackView.image = [UIImage imageNamed:#"search1.gif"];
searchBackView.userInteractionEnabled=YES;
searchBackView.backgroundColor=[UIColor clearColor];
[tableHeader addSubview:searchBackView];
searchBar=[[[UISearchBar alloc] init] autorelease];
searchBar.delegate=self;
[searchBar setKeyboardType:UIKeyboardTypeDefault];
searchBar.barStyle = UISearchBarIconClear;
searchBar.frame=CGRectMake(17, 3, 285, 30);
[searchBar setSearchFieldBackgroundImage:[UIImage imageNamed:#"search1.gif"] forState:UIControlStateNormal];
searchBar.backgroundColor=[UIColor clearColor];
[searchBackView addSubview:searchBar];
[searchBackView release];
[tableHeader addSubview:label];
for (UIView *subView in self.searchBar.subviews)
{
for (UIView *secondLevelSubview in subView.subviews){
if ([secondLevelSubview isKindOfClass:[UIImageView class]]){
[secondLevelSubview removeFromSuperview];
}
}
}
searchField = nil;
for (UIView *subView in self.searchBar.subviews)
{
for (UIView *secondLevelSubview in subView.subviews){
if ([secondLevelSubview isKindOfClass:[UITextField class]])
{
searchField = (UITextField *)secondLevelSubview;
break;
}
}
}
for (UIView *subview in searchBar.subviews)
{
for (UIView *secondLevelSubview in subview.subviews){
if ([secondLevelSubview conformsToProtocol:#protocol(UITextInputTraits)])
{
[(UITextField *)secondLevelSubview setClearButtonMode:UITextFieldViewModeNever];
}
}
}
if (searchField) {
searchField.leftViewMode = UITextFieldViewModeNever;
}
BluemenAppDelegate *delegate=(BluemenAppDelegate*)[[UIApplication sharedApplication] delegate];
if (isShowlist==YES) {
delegate.search_string = #"";
searchBar.text = delegate.search_string;
isShowlist = NO;
}
searchBar.text = delegate.search_string;
Update
Now I am able launch app but now if click on any textfield in app it is crashing and giving XPC connection interrupted error
If I understood correctly, you're trying to achieve a SearchBar with a clear background. As seen on the error message, iOS 13 won't allow UISearchBarBackground to be removed. There is a work around you can try:
This will make the search background image to be transparent, without removing it.
for (UIView *subView in self.searchBar.subviews) {
for (UIView *secondLevelSubview in subView.subviews){
if ([secondLevelSubview isKindOfClass: [UIImageView class]]) {
secondLevelSubview.alpha = 0.0;
break;
}
}
}
Just replace this part of your code with this one and check if it attends what you are expecting.

Finding all UIButtons in subviews

I have a single UIButton in the view of my UIViewController. I also have ten more that are in a subview in the main view. I want to find all these buttons. So far I have:
-(void)findAllButtons{
for(UIView *view in self.view.subviews) {
if ([view isKindOfClass:[myButton class]]){
NSLog(#"found a button!");
}
}
}
It is only finding the single button though and not the other ten. Why is that? Shouldn't it iterate every single subview and then find them?
for (UIView *subView in scroll.subviews) {
if ([subView isKindOfClass:[UIButton class]]) {
UIButton *btn = (UIButton*)subView;
if (btn.tag == selectedButton.tag) {
btn.layer.borderWidth = 1.0f;
btn.layer.borderColor = [UIColor darkGrayColor].CGColor;
}else{
btn.layer.borderWidth = 1.0f;
btn.layer.borderColor = [UIColor clearColor].CGColor;
}
}
}
Just a few lines of code
-(void)findAllButtons {
[self findButtonsInSubviews:self.view.subviews];
}
- (void)findButtonsInSubviews:(NSArray *)subviews {
for(UIView *view in subviews) {
if ([view isKindOfClass:[UIButton class]]){
NSLog(#"found a button!");
} else {
[self findButtonsInSubviews:view.subviews];
}
}
}
A recursive function using Objective-C blocks like this will find all views of a given subclass type as specified in the test block in the view hierarchy of the given view:
NSMutableArray *marrAllButtons = [NSMutableArray new];
BOOL (^viewTest)(UIView*) = ^BOOL(UIView* viewToTest) {
return [view isKindOfClass:[UIButton class]];
};
void(^viewEnumerator)(UIView*) = ^(UIView* outerView){
for (UIView *view in outerView.subviews)
{
if (viewTest(view))
{
[marrAllButtons addObject:view];
}
else
{
viewEnumerator(view);
}
}
};
viewEnumerator(self.view);
NSLog(#"All Buttons %#", marrAllButtons);
- (NSMutableArray *)buttonsInView:(UIView *)view
{
NSArray *subviews = view.subviews;
NSMutableArray *buttons = [NSMutableArray array];
for (UIView *subview in subviews)
{
if ([subview isKindOfClass:[UILabel class]])
{
[buttons addObject:subview];
}
else if(subview.subviews)
{
[buttons addObjectsFromArray:[self buttonsInView:subview]];
}
}
return buttons;
}
Your method is right if all your button already have in self.view (main view).
Just set tag for all button to check and also make sure that all button are on the main view. I hope this will work.
-(void)findAllButtons{
for(UIView *view in self.view.subviews) {
if ([view isKindOfClass:[myButton class]]){
UIButton *button = (UIButton*)view;
NSLog(#"found a button with tag:%d",button.tag);
}
}
}
for(UIView * subView in view.subviews) // here write Name of you ScrollView.
{
// NSLog(#"test %#", [subView class]);
if([subView isKindOfClass:[UIButton class]])
{
UIButton *button = (UIButton*)subView;
[button setSelected:NO] ;
NSString *s1;
s1 = #",";
s1 = [s1 stringByAppendingString:[NSString stringWithFormat:#"%#",button.titleLabel.text ]];
s1 = [s1 stringByAppendingString:[NSString stringWithFormat:#"%#",#"," ]];
NSRange range = [temp_Colors_Name_comma rangeOfString:s1 ];
if(range.location == NSNotFound)
{
}
else
{
[button setSelected:YES];
}
}
}

Disable interaction for views behind background image

To show a help view I've put an UIImageView which behind has some UIButtons. How can I disable user interaction of these buttons? If I touch this image where buttons are behind, they responds to touch events.
CODE FOR IMAGE BACKGROUND:
self.helpBackground = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
self.helpBackground.backgroundColor = [UIColor colorWithWhite:0 alpha:0.75];
self.helpBackground.hidden = YES;
[self.view addSubview:self.helpBackground];
I've used self.helpBackground.userInteractionEnabled = NO; but didn't work.
Thanks.
Put your buttons in a array and loop through them and disable them:
NSArray *buttonsArray = #[yourButton1, yourButton2];
for (UIButton *button in buttonsArray) {
button.enabled = NO;
}
And when you want them enabled just loop again and set enabled to YES
Keep a Tag to your helpView(imageview) and add the following code
for (UIView *view in self.view.subviews) {
if (view.tag != yourViewTag) {
view.userInteractionEnabled = NO;
}
}
And after removing the help screen use the following code
for (UIView *view in self.view.subviews) {
view.userInteractionEnabled = YES;
}
you can try below solution..When help imageview is appearing
for (UIView *view in [self.view subviews])
{
if (view isKindOfClass:[UIButton Class])
{
view.userInteractionEnabled = NO;
}
else
{
view.userInteractionEnabled = YES;
}
}
////After dismissing the help screen you can
for (UIView *view in [self.view subviews])
{
if (view isKindOfClass:[UIButton Class])
{
view.userInteractionEnabled = YES;
}
}
////(OR) Simply do as below
self.view.userInteractionEnabled=YES;
Hope it helps you..
You can create a method that disables user interaction for all views that are under your helpBackground:
- (void)disableUserInteractionForViewsUnderView:(UIView *)view
{
CGRect area = view.frame;
for (UIView *underView in [self.view subviews]) {
if(CGRectContainsRect(area, underView.frame))
underView.userInteractionEnabled = NO;
}
}
and after that you call it where you need it:
[self disableUserInteractionForViewsUnderView:self.helpBackground];
EDIT
I've created a UIViewController category gist on github.com. You can find it here: https://gist.github.com/alexcristea/0244b50e503e8bf4f25d
You can use it like this:
[self enumerateViewsPlacedUnderView:self.helpBackground usingBlock:^(UIView *view) {
if ([view isKindOfClass:[UIButton class]]) {
view.userInteractionEnabled = NO;
}
}];

UIImageView animation starts and low memory warning occurs

I have an issue with my ImageView animation. In my view there are more than 10 views and each view have are identified from its tag value & I have UIImageView and UIButton. when a button is tapped then that particular image of the view have to be animated. If any other images are animated it have to be stopped. This is my code:
-(void)makeAnimation:(UIButton *)sender {
UIView *tagView=(UIView *)[self.view viewWithTag:sender.tag];
UIView *next=nil;
UIView *previous=nil;
NSLog(#"%d",sender.tag);
for (UIImageView * imageview in [tagView subviews]) {
if ([imageview isKindOfClass:[UIImageView class]]) {
if ([imageview isAnimating]) {
NSLog(#"Animation Happens");
}
else{
imageview.animationDuration=2.0;
imageview.animationImages=[animationArray objectAtIndex:sender.tag-1];
imageview.animationRepeatCount=2;
imageview.tag=sender.tag;
[imageview startAnimating];
}
}
}
next=(UIView*)[self.view viewWithTag:sender.tag+1];
previous=(UIView*)[self.view viewWithTag:sender.tag-1];
NSLog(#"NOT IDEA");
[self previousview:previous nextview:next];
}
-(void)previousview:(UIView *)previous nextview:(UIView*)next
{
for (UIImageView * imageview in [previous subviews]) {
if ([imageview isKindOfClass:[UIImageView class]]) {
[imageview stopAnimating];
NSLog(#"PRREVIOUS");
}
}
for (UIImageView * imageview in [next subviews]) {
if ([imageview isKindOfClass:[UIImageView class]]) {
[imageview stopAnimating];
NSLog(#"NEXT");
}
}
}
Now my issue is when I select more than 4 buttons one after another my app crashed with memory warning.
Find the exact location of leak using profile while running and use #autorelease{} to handle the memory manually
Like this..
-(void)makeAnimation:(UIButton *)sender {
#autorelease{
UIView *tagView=(UIView *)[self.view viewWithTag:sender.tag];
UIView *next=nil;
UIView *previous=nil;
NSLog(#"%d",sender.tag);
for (UIImageView * imageview in [tagView subviews]) {
if ([imageview isKindOfClass:[UIImageView class]]) {
if ([imageview isAnimating]) {
NSLog(#"Animation Happens");
}
else{
imageview.animationDuration=2.0;
imageview.animationImages=[animationArray objectAtIndex:sender.tag-1];
imageview.animationRepeatCount=2;
imageview.tag=sender.tag;
[imageview startAnimating];
}
}
}
next=(UIView*)[self.view viewWithTag:sender.tag+1];
previous=(UIView*)[self.view viewWithTag:sender.tag-1];
NSLog(#"NOT IDEA");
[self previousview:previous nextview:next];
}
}

Using isKindOfClass: I don't understand why this code is behaving this way

-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image = [UIImage imageNamed:#"Sample.png"];
[self.view addSubview:imageView];
NSArray *subviews = [self.view subviews];
for(id element in subviews) {
if ([[element class] isKindOfClass:[UIImageView class]]) //check if the object is a UIImageView
{
NSLog(#"element is a UIImageView\n");
[element setCenter:CGPointMake(500., 500.)];
} else {
NSLog(#"element is NOT a UIImageView\n");
}
}
}
I expected the output to be "element is a UIImageView, but it's actually element is NOT a UIImageView. Why? It's not that there are other subviews. There is only one. Furthermore, when run, the image is displayed at 100,100, not 500,500 as expected.
Your check is wrong. You should call isKindOfClass: on object and not on class of object.
[element isKindOfClass:[UIImageView class]]
Try the Following code.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image = [UIImage imageNamed:#"Sample.png"];
[self.view addSubview:imageView];
NSArray *subviews = [self.view subviews];
for(UIView *view in subviews) {
if ([view isKindOfClass:[UIImageView class]]) //check if the object is a UIImageView
{
NSLog(#"element is a UIImageView\n");
[element setCenter:CGPointMake(500., 500.)];
} else {
NSLog(#"element is NOT a UIImageView\n");
}
}
}
You can also Check sub views by tag value:
initially set imageView.tag=101; //anything you want
for(UIView *subview in [view subviews]) {
if(subview.tag== 101)/*your subview tag value here*/
{
NSLog(#"element is a UIImageView\n");
} else {
NSLog(#"element is NOT a UIImageView\n");
}
}

Resources