I have a custom UITableViewCell in which i create an Icon like this:
self.icon = [[UIImageView alloc] initWithFrame:CGRectMake(15, 15, 50, 50)];
[self.icon setImage:[AppearanceProxyController getImageForAssetIdentifier:#"import"]];
[self addSubview:self.icon];
which works just fine. In addition there is my method to hide the icon:
-(void)hideIcon{
dispatch_async(dispatch_get_main_queue(), ^{
[self.icon setHidden:true];
});
}
which ... has no effect at all and i have no clue why.
the method is called when the cell is tapped from its tableviewcontroller.
the check states it as hidden but it is not.
UIImageView: 0x17d37d20; frame = (15 15; 50 50); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17f8f4c0>> is hidden: 1
setting the uiimage to nil od the alpha to 0.0 has no effect either. What am i doing wrong?
You probably have more than one UIImageView instance, but only have a reference to the latest one. When you hide that, you'll see the old instance underneath which (if they show the same image) looks like hiding didn't work.
So you need to make sure that you call removeFromSuperview on the old instances or need to make sure that you don't create more than one.
Your problem is you are creating self.icon in every uitableview cell.
You alloc init the icon every time so self.icon hold the last object which you alloc init. if you hide the self.icon then it hides the last object.
So If you want to hide some image view just pass this object in your hide icon method like this
-(void)hideIcon : (UIImageView *)imageView{
dispatch_async(dispatch_get_main_queue(), ^{
[imageView setHidden:true];
});
}
And call it when you want to hide
Related
I have searched all over but haven't found the answer that works for me.
I just want a tableview background to be set with an Image and a Text below the image when there are no items in the tableview. Like this:
http://i.stack.imgur.com/7DZa5.png
It also has to be in the center and has to work in both iPhone and IPad.
I have tried setting the tableview background to an ImageView but I can't get the label to be positioned below the image. I have also tried creating a separate .xib file for this but I can't get it to work. Please help!
Do you believe in magic ? Kidding...
I believe its not the background of table view. Whenever the array populating your table view contains no data, you need to remove the table view (_tableView.hidden = YES; WILL WORK) and add this custom view with your image and label.
Why don't you set the UITableView's background property to clear. Then just set the image as the background of the view it self? Using AutoLayout will help you keep it centre at all times.
Hi i have done it using ImageView and setting a label inside the imageview.. then adding the imageview as the background for the tableview. It works on iphone and ipad. here is the code:
UIImage *image = [UIImage imageNamed:#"ico_file_list_not_found.png"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image = image;
[imageView setContentMode:UIViewContentModeCenter];
UILabel *messageLbl = [[UILabel alloc] initWithFrame:CGRectMake(self.tableView.bounds.size.width/2 - image.size.width / 2 + (image.size.width/7),
self.tableView.bounds.size.height/2 + image.size.height / 2
, 120, 21)];
messageLbl.text = #"No files found.";
[imageView addSubview:messageLbl];
self.tableView.backgroundView = imageView;
thank you
It work for you
1> IBOutlet lblTextlable and imgNoItem
2> you set the UITableView's background property to clear.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (arrTableListItem.count==0) {
lblTextlable.hidden = false;
imgNoItem.hidden = false;
}
else {
lblTextlable.hidden = true;
imgNoItem.hidden = true;
}
return arrTableListItem.count;
}
As I see in that image, it's the label and image. So the code logic maybe as follow:
If there is no item in list view, hide it and "show" the image / label.
If there are at least one item in the list view, show the list view and hide the Image / Label.
the user should be able to select one icon from a large number of different icons. I have created a picker dialog that allows the user to make his selection. The ViewController that is used for this picker only holds one UIScrollView. In viewDidLoad for each icon a button is added to the ScrollView. To select an icon the user just has to click the corresponding button...
This works fine, but the ViewController/picker needs several seconds to be displayed. This is because of the many alloc / add operations within viewDidLoad. Because of this I tried to move these options into a background thread. This workes fine, but the created buttons are not visible any more:
- (void)viewDidLoad {
[super viewDidLoad];
self.iconsScrollView.hidden = true;
[self.activityIndicator startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
iconContainer = [[UIView alloc] init];
iconContainer.backgroundColor = [UIColor clearColor];
iconButtons = [[NSMutableDictionary alloc] init];
CGRect buttonRect = CGRectMake(5, 5, 40, 40);
selectedButton = nil;
NSArray *iconInfos = [[StoreController sharedController] allIcons];
for (IconInfo* iconInfo in iconInfos) {
NSString *iconName = iconInfo.name;
UIButton *iconButton = [UIButton buttonWithType:UIButtonTypeCustom];
iconButton.frame = buttonRect;
[iconButton addTarget:self action:#selector(iconSelectionClick:) forControlEvents: UIControlEventTouchUpInside];
[iconButton setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];
[iconContainer addSubview:iconButton];
[iconButtons setObject:iconButton forKey:iconInfo.guid];
buttonRect.origin.x += 50;
if (buttonRect.origin.x > 205) {
buttonRect.origin.x = 5;
buttonRect.origin.y += 50;
}
}
iconContainer.frame = CGRectMake(0, 0, self.iconsScrollView.frame.size.width, ceil([iconButtons count] / 5.0) * 50);
dispatch_async(dispatch_get_main_queue(), ^{
[self.iconsScrollView addSubview:iconContainer];
self.iconsScrollView.contentSize = iconContainer.frame.size;
[self.activityIndicator stopAnimating];
self.iconsScrollView.hidden = false;
[self.view setNeedsDisplay];
});
});
}
This works (almost) without any problem:
Picker ViewController is presented
ActivityIndicator is visible while buttons are created
Once all buttons are ready ActivityIndicator stops and the ScrollView becomes visible.
Only Problem: The Buttons are not visible. The ScrollView can be used normally (content size correct) and when I touch inside the ScrollView and hit an invisible button the click selector is called. Thus all buttons are there but not visible. Eventually after 10-15 seconds all Buttons become visible at once.
Using setNeedsDisplay or setNeedsLayout for the View, the ScrollView, or the buttons does not change anything.
Any idea what I can do?
You are adding buttons to a subview while you aren't on the main thread.
Generally, UIKit code should only be run on the main queue.
UIKit can only be updated from the main thread
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
});
I call this method in my ViewController, which contains a UIScrollView, when the user taps a button.
-(void) updateView:(NSURL *) urlPicture{
UIImageView *imageNews = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,300,200)];
imageNews.contentMode = UIViewContentModeScaleAspectFit;
[imageNews setImageWithURL:urlPicture];
[self.scrollView addSubview:imageNews];
}
It seems to work fine, but when I got a strange behavior.
It doesn't clear the previous image to put the new one.
E.g: if the first image is 300x200 and the second one is 200x200 I still can see the sides of the first one when the app download the second.
I would like to know how to clear the previous image before download the second.
I already try imageNews.image = nil; but it didn't work
First you need to remove old view from scrollView. You can edit your code as mentioned below
#define IMAGE_VIEW_TAG 1001
-(void) updateView:(NSURL *) urlPicture{
UIView *oldView = [self.scrollView viewWithTag:IMAGE_VIEW_TAG];
if(oldView)
[oldView removeFromSuperView]
UIImageView *imageNews = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,300,200)];
imageNews.tag = IMAGE_VIEW_TAG;
imageNews.contentMode = UIViewContentModeScaleAspectFit;
[imageNews setImageWithURL:urlPicture];
[self.scrollView addSubview:imageNews];
}
Well I am not really sure what your application does ,
but seems like you need to have only 1 image
so I would suggest you to remove the previous image.
There are 2 ways to do so:
1) you could use your image as property and simply call [_imageNews removeFromSuperView];
2) you can iterate through your self.scrollView's sub views and remove it from there.
I'm using muZZkat's custom range slider: NMRangeSlider#github1
But i need to fade the slider. When i create the range slider, i put it into a content view. I've tried setting the alpha of the content view to .7
UIView *sliderView = [self configureLabelSliderWithSize:CGSizeMake(300, 70)];
sliderView.alpha = .4;
but it does not give the desired effect:
The UIImageView upperHandle and lowerHandle also fade out which shows the background track (the blue part). I'd rather have the handle's alpha be higher so you can't see the blue part behind it.
I tried adding a method to the ranger slider class:
-(void)toggleAlpha {
self.trackBackground.alpha = .3;
self.track.alpha = .3;
self.lowerHandle.alpha = .3;
self.upperHandle.alpha = .3;
}
but this does not change the alpha at all.
The UIImageViews are all initalized in the -(void)addSubviews method:
- (void) addSubviews
{
//------------------------------
// Track Brackground
self.trackBackground = [[UIImageView alloc] initWithImage:self.trackBackgroundImage];
self.trackBackground.frame = [self trackBackgroundRect];
//------------------------------
// Track
self.track = [[UIImageView alloc] initWithImage:self.trackImage];
self.track.frame = [self trackRect];
//------------------------------
// Lower Handle Handle
self.lowerHandle = [[UIImageView alloc] initWithImage:self.lowerHandleImageNormal highlightedImage:self.lowerHandleImageHighlighted];
self.lowerHandle.frame = [self thumbRectForValue:_lowerValue image:self.lowerHandleImageNormal];
//------------------------------
// Upper Handle Handle
self.upperHandle = [[UIImageView alloc] initWithImage:self.upperHandleImageNormal highlightedImage:self.upperHandleImageHighlighted];
self.upperHandle.frame = [self thumbRectForValue:_upperValue image:self.upperHandleImageNormal];
[self addSubview:self.trackBackground];
[self addSubview:self.track];
[self addSubview:self.lowerHandle];
[self addSubview:self.upperHandle];
}
and if i set their alpha lower here, it works.
I don't understand why i can't alter the alpha from anywhere else?
I just added the NMRangeSlider-Demo and checked it out.
I think the problem is that you're probably calling toggleAlpha in viewDidLoad method, right?
You should instead call in the viewDidAppear method, since layoutSubviews method (which in turn calls addSubview) in the NMRangeSlider class, is called after viewDidLoad and before viewDidAppear, so whatever you do in viewDidLoad will be reset as the subviews are initialized in addSubview method.
Just adding toggleAlpha in viewDidAppear worked for me.
I'm using a double for loop to add UIButtons to a UIScrollView in a grid format. These UIButtons take time to load as they have subviews that are UIImageViews which get their UIImages by downloading data off the internet.
Right now, the subviews don't show until AFTER the method completely finishes executing. Correct me if I'm wrong, but I'm guessing xcode doesn't show added subviews until a method is done executing.
However, I do want to show each subview getting added one at a time, as a cool loading effect. How would I implement this?
Thanks!
You should use multiple threads to load your pictures so that your main thread does not become sluggish. I recently wrote something similar...Take a look at my code from my viewWillAppear method:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.myImages = [self.myModel retrieveAttachments]; //Suppose this takes a long time
for (UIImage *image in self.myImages)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self addImageToScrollView:image animated:YES]; });
}
}
});
The addImageToScrollView method would be like so:
-(void) addImageToScrollView: (UIImage *) image animated: (BOOL) animated
{
//Create image view
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.image = image;
if(animated)
{
imageView.alpha = 0;
[self.myScrollView addSubview:imageView];
[UIView animateWithDuration:ADD_IMAGE_APPEARING_ANIMATION_SPEED animations:^{
imageView.alpha = 1;
}];
}
else
{
[self.myScrollView addSubview:imageView];
}
}