How to remove a subview from a cell's content view? - objective-c

I have added a UIWebview to the cell's content view
UIWebView *webview = [UIWebView alloc]init];
[cell.contentView addSubview:webview];
Now I intend to remove 'webview' from the cell's contentview.
Can I do the following?
Method 1:
[webview removeFromSuperview];
Or do I really need to loop through all the subviews of the contentview before removing it?
Method 2:
for (UIView *subview in [self.contentView subviews])
{
if ([subview isKindOfClass:[UIWebView class]])
{
[subview removeFromSuperview];
}
}
I tried method 1 and it didn't seem to work, am not sure if I am missing something or if method 2 is the only way to go

Method 1 should work, but are you sure that the web view you're removing is really the same as the one you added? A simple way to remove a given subview from a view is to assign a tag:
//...
webView.tag = 123;
[cell.contentView addSubview:webView];
//...
[[cell.contentView viewWithTag:123] removeFromSuperview];
In practice it would of course be better to use a named constant as the tag.

//creating
// cell.bounds will fill up the cell with your webview
UIWebView *webview = [[UIWebView alloc]initWithFrame:cell.bounds];
webview.tag = 11;
[cell.contentView addSubview:webview];
//removing
[[cell.contentView viewWithTag:11] removeFromSuperview];

You can just use removeFromSuperview. What do you mean by "didn't seem to work?" The most likely problem is that webview is nil at the point that you called removeFromSuperview (or is pointing to some other view). Make sure it's pointing to the view you mean.

I believe that your webview is nil when actually trying it to remove from the superview. Have you tried reloading table data after removing it from the content view? In which methods are you doing view manipulation? Datasource/delegate or custom IBActions?

Related

Can't programmatically move label in viewDidLoad

I'm trying to move a uiLabel down a drop if it's an iPhone 5 (4" display). But it's not working when the code is in viewDidLoad. If I call the code from clicking a uiButton, it works. Here's the code:
-(void) viewDidLoad {
if(CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size,CGSizeMake(640, 1136))) {
CGRect frame = [self.timeOnCurrentQuestion frame];
frame.origin.y += 40; // change the location
[self.timeOnCurrentQuestion setFrame:frame];
nslog(#"This DOES get logged");
}
}
Jonah, have you tried your code in viewWillAppear method? Possibly, it'll sort-out your issue.
Maybe that are something you need to beware of.
- (void)viewDidLoad
It is a method that when the controller juz created its view.
for example:
maybe in your init method, you call something like:
[self.view setBackground:[UIColor redColor]];
self.timeOnCurrentQuestion = [[UIView alloc] initWithFrame:kFrame];
In this case the work flow will be like this:
[self.view setBackground:[UIColor redColor]];
[self viewDidload];
self.timeOnCurrentQuestion = [[UIView alloc] initWithFrame:kFrame];
Th reason for this work flow is because the self.view is called, then its view is needed before the normal view cycle, so , in this case, self.timeOnCurrentQuestion is still nil in the viewDidload method.
I don't know if my practice is the best or not.
I always init the subView in the controller's init method.
and do the [self.view addSubview:_subview] (//or everything method call that require the self.view) in [self viewDidload];
viewDidAppear worked for me. The life cycle seems to be
LoadView()
viewDidLoad()
viewWillAppear()
viewDidAppear()

How do I Insert View in Superview's View? (iOS) [duplicate]

I have the line of code below... How would I modify it to insert the subview in the superview's view named 'foo'?
[[self superview] addSubview:copy3];
There are more than 1 ways of doing this -
1.have an IBOutlet reference in your code. This is created from xcode Interface builder. Once you have this then it fairly straight forward -
[iboutlet_foo_object addSubview:copy3];
2.tag the view that you are interested in. Again tagging a view can be done from xcode Interface builder or from code. After that -
Foo *fooObj = [[self superview] viewWithTag:tagInt];
[fooObj addSubview:copy3];
3.Finally you can iterate through all the views in your superview & see which one is of type Foo -
NSArray *subviews = [[self superview] subviews];
for(UIView *v in subviews)
{
if(v isKindOfClass:[Foo class])
{
[v addSubview:copy3];
break;
}
}
hope these methods help you...
First make myView into a property of the superview
Then use
[[[self superview] myView] addSubview:mySubview];
First tag the view myView with a unique number:
myView.tag = 0x1234;
Then you can find it using viewWithTag:
[[[self superview] viewWithTag:0x1234] addSubview:mySubview];
You might just actually add it to 'view' instead of 'superview'.
[[self view] addSubview:mySubview];
It works just fine for me, whenever I add subviews to my parent view.
Let me know if something went wrong.

How to Insert View in Superview's View? (iOS)

I have the line of code below... How would I modify it to insert the subview in the superview's view named 'foo'?
[[self superview] addSubview:copy3];
There are more than 1 ways of doing this -
1.have an IBOutlet reference in your code. This is created from xcode Interface builder. Once you have this then it fairly straight forward -
[iboutlet_foo_object addSubview:copy3];
2.tag the view that you are interested in. Again tagging a view can be done from xcode Interface builder or from code. After that -
Foo *fooObj = [[self superview] viewWithTag:tagInt];
[fooObj addSubview:copy3];
3.Finally you can iterate through all the views in your superview & see which one is of type Foo -
NSArray *subviews = [[self superview] subviews];
for(UIView *v in subviews)
{
if(v isKindOfClass:[Foo class])
{
[v addSubview:copy3];
break;
}
}
hope these methods help you...
First make myView into a property of the superview
Then use
[[[self superview] myView] addSubview:mySubview];
First tag the view myView with a unique number:
myView.tag = 0x1234;
Then you can find it using viewWithTag:
[[[self superview] viewWithTag:0x1234] addSubview:mySubview];
You might just actually add it to 'view' instead of 'superview'.
[[self view] addSubview:mySubview];
It works just fine for me, whenever I add subviews to my parent view.
Let me know if something went wrong.

adding subviews to UITableViewCell's content view makes cell unselectable

I want to add some static text to a UITableViewCell in a UITextView.
UITextView *addressField = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 75)];
[addressField setBackgroundColor:[UIColor clearColor]];
[addressField setFont:[UIFont fontWithName:#"HelveticaNeue" size:14]];
[addressField setContentInset:UIEdgeInsetsMake(0, 20, 0, 0)];
[addressField setEditable:NO];
[addressField setScrollEnabled:NO];
// change me later
[addressField setText:#"John Doe\n555 Some Street\nSan Francisco, CA, 00000"];
[cell.contentView addSubview:addressField];
[addressField release];
This works great but I this code makes the cell unselectable probably because the UITextView is covering the entire cell.
How can I work around this so that I can have both the UITextView and selectable cells?
btw, I could make the UITextView size a bit smaller but users would still not be able to select the cell if they touch the UITextView.
I think a slightly better way to do it is to create a tap gesture recognizer on the entire table. (For example in your viewDidLoad)
// gesture recognizer to make the entire cell a touch target
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(changeFocus:)];
[tableView addGestureRecognizer:tap];
[tap release];
Then you create a selector (changeFocus: in this case) to do the actual selecting.
- (void)changeFocus:(UITapGestureRecognizer *)tap
{
if (tap.state == UIGestureRecognizerStateEnded)
{
CGPoint tapLocation = [tap locationInView:self.tableView];
NSIndexPath* path = [self.tableView indexPathForRowAtPoint:tapLocation];
[self tableView:self.tableView didSelectRowAtIndexPath:path];
}
}
You can make your changeFocus method more elaborate to prevent selections or give focus to specific subviews of the selected indexPath.
I would adopt the following approach in order to keep interaction enabled with both the UITextView and the UITableViewCell.
Declare your controller class (a UITableViewController I guess ?) as UITexView delegate.
When you declare your UITextView, set the table view controller as it's delegate.
Implement one of the UITextViewDelegate methods (ex : - (void)textViewDidChangeSelection:(UITextView *)textView) in your table view controller .m file.
From within this method you can manipulate the targeted cell either with a custom code or by triggering the tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *) delegate method through selectRowAtIndexPath:animated:scrollPosition:.
Your code might then look like :
In the table view controller .h file :
#interface MyTableViewController : UITableViewController <UITextViewDelegate> { ...
...
}
In the table view controller .m file :
UITextView *addressField = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 75)];
[addressField setDelegate:self];
...
Then implement this function for example (or any other suitable UITextViewDelegate function) :
- (void)textViewDidChangeSelection:(UITextView *)textView {
// Determine which text view triggered this method in order to target the right cell
...
// You should have obtained an indexPath here
...
// Call the following function to trigger the row selection table view delegate method
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone]
}
Note that there are other alternatives like subclassing UITextView and deal with it's touch methods. I would recommend to use the possibilites offered by its delegate protocol though.
Note also that it might be handy to have your UITextView declared or at least referenced as an instance variable of the table view controller class. This will help you easily keep track of which addressField was hit and get the right indexPath.
[addressField setUserInteractionEnabled:NO];
I hope this helps you a bit:
[self.view insertSubview:TextView aboveSubview:TableView];
Or vice-versa based on your requirements.

Objective-C: How can I remove just one subview from UIWindow?

I want to remove just 1 subview not all.
And That subview is UIWebView.
You can call this on the UIWebView you want to remove:
[myWebView removeFromSuperview];
This method is available to all subclasses of UIView and NSView.
You can also try this if you do not declare an instance var in your header file.
for(UIView *view in window.subViews){
if([view isKindOfClass[UIWebView class]]){
[view removeFromSuperview];
}
}
Additionally, if you don't have a reference to it, just give a tag when you created it like this
myWebView.tag = 1234;
And remove it like this
[[myParentView viewWithTag:1234] removeFromSuperview]