Add view controller to UICollectionViewCell - ios

I have viewController that have fabric create methods, depending on specific integer. What i want is, to make collection view, with each cell is representing that controller.
Problem is, UICollectionViewCell is a view, but I've ViewController.
What I tried is subclass UICollectionViewCell like follow (paste that code in subclass of UICollectionViewCell):
CalendarViewController *vc = [CalendarViewController create];
UIView *vw = vc.view;
[self addSubview:vw];
[vw mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.bottom.equalTo(self);
}];
Last line is simply added constraints.
Now I've 2 problems:
It treated like a view, and i cant click on specific areas (cells, CalendarViewController is collection view also)
Sometimes view vanish and there is only blank view on a screen.

View controller in UICollectionViewCell is a tricky situation as it is respective view controller's responsibility to handle views touches. You can refer to this SO answer for some approaches.
But, this situation when UICollectionViewCell needs to be a UIViewController is handled here: https://github.com/zats/Voltron, if you can use third party code:

Related

Add view behind tableview in UITableViewController

I'm trying to add this custom control below my tableview in a TableViewController:
https://github.com/zogieosagie/RMEIdeasPullToSortControl
In the example the creator gives, the control is implemented using a ViewController and an added tableview, but I want to use it in a TableViewController. I have created and initialized it as shown in the example but I cannot get it to show up behind the table. Any ideas?
Here is a screenshot of the control above my tableview: https://www.dropbox.com/s/ojfpacxelcy9cqm/Photo%20May%2028%2C%208%2057%2035%20PM.png
Here is my code in the viewDidLoad method:
[self.tableView setBackgroundColor:[UIColor clearColor]];
self.rmeideasPullDownControl = [[RMEIdeasPullDownControl alloc] initWithDataSource:self delegate:self clientScrollView:self.tableView];
self.sortTitlesArray = [[NSArray alloc] initWithObjects:#"Listed from A - Z", #"Listed from Z - A", #"Brand value: HIGHEST - LOWEST", #"Brand value: LOWEST - HIGHEST", #"Founded: OLDEST - NEWEST", #"Founded: NEWEST - OLDEST", nil];
CGRect originalFrame = self.rmeideasPullDownControl.frame;
self.rmeideasPullDownControl.frame = CGRectMake(0.0, 45.0, originalFrame.size.width, originalFrame.size.height);
//It is recommended that the control is placed behind the client scrollView. Remember to make its background transparent.
//[self.view insertSubview:self.rmeideasPullDownControl belowSubview:self.tableView];
[self.tableView addSubview:self.rmeideasPullDownControl];
[self.tableView sendSubviewToBack:self.rmeideasPullDownControl];
Table view controllers do not lend themselves to managing anything other than a table view. In a table view controller the content view of the view controller is the table view.
You should not try to add other views as subviews of a table view.
Those 2 things combined mean that you can't do what you are trying to do.
Instead, you should create a regular UIViewController. In your storyboard, add a container view to the view controller's content view. Create a UITableViewController as a separate scene, and then control-drag from the container view onto the table view controller. That will set up an embed segue, so your table view controller becomes a child view of the regular view controller. Now you can do whatever you want to the main view controller's content view, including adding other views behind the table view.
Do you mean that you are using a Table View Controller on the storyboard? Or do you mean that your backing code is a subclass of UITableViewController?
I haven't used this project before but I'm guessing you are using a Table View Controller on the storyboard, in which case there is no backing view for the RMEIdeasPulldownControl to attach to (the top-level view is a UITableViewController). If you look in the example it needs to be attached to a scrollview (like a table view) but it needs to be inserted into a view (like a UIView)
If you meant the second one then I'm not sure, UITableViewControllers are subclassed from UIViewControllers and are really very similar, so I can't imagine any trouble arising from that.
It isn't possible directly, but you can create UIViewControllerClass with relevant storyboard UIViewController
add a MyUIView in hierarchy then UITableView next to MyUIView
attach datasource and delegates for UITableView and use MyUIView as per your requirement.

is it good to use ViewCntroller's view in icarousel?

in carousel viewForItemAtIndex i am using reuse view something like this-
-(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view{
if (!view){
UIViewController * viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PopUpView"];
view = [viewController.view viewWithTag:1];
CGRect Frame = CGRectMake(view.frame.origin.x+300, view.frame.origin.y, view.frame.size.width+300, view.frame.size.height-350);
view.frame = Frame;
}
Is it a good approach?
I would say that this is not a good approach. You are creating a view controller here only to immediately throw it away, which is pointless.
If you just need the view, you can load it directly from a nib file without needing a view controller. You can bind it's actions to the main view controller for the carousel (there is an example of this in ControlsExample project included with the library), or create a custom view class and bind the subview outlets to the view itself.
If you want to use a view controller for each carousel item view (which I don't recommend, as this is not the convention used for UITableView or UICollectionView, which iCarousel is modelled on) then you should add the view controller as a child view controller of the main carousel controller, but this is fiddly as there is no obvious place where you can remove the child controller again when its view goes offscreen).
As per approach, there is nothing wrong in using a view controller's view. UIView is where you handle what it looks like, UIViewController is the class where you handle events. If you want to handle any events then using UIViewController's View is a better option.

tableView initwithframe and storyboard

I'm trying to add a tableview as subview to my tableViewController, but I want to setup the cells in storyboard. It will be a static tableview.
This is the code for calling the tableview on button click.
- (IBAction)botaoAdicionar:(id)sender {
AtividadesPraticadasTableView *tableview = [[AtividadesPraticadasTableView alloc] initWithFrame:CGRectMake(0, 170, 320, 320) style:UITableViewStylePlain];
[self.view addSubview:tableview];
}
In the tableview class I have this:
#implementation AtividadesPraticadasTableView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
Now, I have a viewcontrollerin storyboard with a tableview, which the class of the tableviewI changed to this file AtividadesPraticadasTableView. It has three static custom cells in storyboard, therefore it opens a blank default tableview.
What am I missing?
Static table views are entirely contained within the storyboard, and require information from the storyboard to display their content.
You've defined a static table view controller in the storyboard, populated it and set the tableView's custom class to your custom class, but when you want to add the table view you are just instantiating a table view of that class. That isn't going to get any of the information you've added to the storyboard.
In addition, the static cells information is read and understood by the UITableViewController, not the UITableView, so you are at the wrong level there too.
You need to do the following:
Get a reference to the storyboard, either from your original view controller's storyboard property (if it is on the same storyboard as your static table) or using storyboardWithName:bundle:.
instantiate the table view controller from that storyboard, using instantiateViewControllerWithIdentifier:. This will create a table view controller object containing all your static cells
Add this as a child view controller to your original view controller, using addChildViewController:
Add the table view controller's tableView as a subview
It may be simpler to add a container view in the storyboard to hold this view, and reveal it when the button is pressed, as Mike Slutsky suggested - this will do all of the instantiating and adding and child view controller-ing work for you, but the principle is still the same.
Also, adding a table view as a subview to a table view controller sounds very dodgy - a table view controller already has a table view as its view, and you can't really add subviews to that.
The thing your missing is the association between the programatically instantiated tableview and the UITableView that you put in your storyboard. You cannot just draw UITableViews in your storyboard and start instantiating new UITableViews in the controller's code and expect xcode to know which UITableView you wanted to use from the storyboard. Use an IBOutlet to connect a global variable for the controller to the UITableView in the storyboard, then the controller will know what you're trying to refer to. If you want that UITableView to appear on a button click, simply set the UITableView to hidden by default in the storyboard and then unhide it when the button is pressed.
The thing You are missing called manual. Check this protocol for TableView dataSource https://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITableViewDataSource
P.S. Here good tutorial for storyboards http://maniacdev.com/ios-5-sdk-tutorial-and-guide/xcode-4-storyboard

Should i create a view ( consisting UIButton, UILabel etc) in a separate UIView class or inside UIViewController?

I have a UIViewController say viewControllerA which contains some view element like UIButton, UILabel etc. Now my question is should I create those view elements in a separate UIView class and then add in UIViewController, or should I create those view elements directly inside the UIViewController. Accordingly to MVC isn't it appropriate to create view elements inside a separate UIView class and then add this in UIViewController?
The standard place to build the view hierarchy in a UIViewController is in the -viewDidLoad method. That method gets called whenever the UIViewController's view is created. The view controller's view will be loaded from the NIB/Storyboard if applicable; your outlets will be wired up; and then -viewDidLoad is called for you to perform further customization:
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0,0.0,100.0,40.0)];
[self.view addSubView:aLabel];
}
In Cocoa/Cocoa Touch you don't always want to subclass everything the way you would in, say, Java. There are often other preferred means of extending the functionality in built-in classes such as Objective-C categories, delegation, and pre-defined properties.
It's certainly possible to do this sort of thing another way, but this is the most "Cocoa-like" way to do it. Actually, the most "Cocoa-like" way would be to create the view hierarchy in Interface Builder, but if you want to do it programmatically this is the usual way.

Using static cells without a UITableViewController [duplicate]

I'm using XCode 4.2 and have built my UI using Storyboards. I need to create a view that has content above and below a UITableView and I can achieve this by using a UIViewController. A UITableViewController does not let you add content above or below the table. You can use the table header/footer but that doesn't work for what I would like to achieve.
I now have a UIViewController with a UITableView embedded in it. I can adjust the height and width of the UITableView accordingly which provides me the UI layout that I am looking for.
I can customize the static cells in the UITableView but when I try to build I get the following error:
Illegal Configuration: Static table views are only valid when embedded in UITableViewController instances
My question is how are others getting around this? Creating a tableview with static cells and laying them out visually is very nice but apparently that is not allowed for some reason that I cannot understand. I can't switch to a UITableViewController because of my visual layout requirements.
Any assistance would be greatly appreciated.
You can achieve this in Xcode 4.5 and later versions, assuming your app is targeted at iOS 6+.
In the Storyboard simply create a UIViewController with a View Container inside it's main view. Then hook up that View Container to a UITableViewController that contains static cells.
Just like this:
You don't need a single line of code. Just control click, drag and select embed. The view controller containment is handled for you.
You are right. In storyboard, you cannot have a tableView with static cells embedded in a viewController. One way around it (I have not tried it myself, though, so I am not sure if it works) can be that you create an instance of UITableViewController in storyboard with static cells. Add an instance of UIView to your viewController, and then programmatically load the tableView of the UITableViewController into the UIView of your viewController.
pmd's answer works but in the event that backward compatibility with iOS 5 is required as well, you can do the embedding programatically using the View Containment API.
In the viewDidLoad method of your parent UIViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
MyTableViewController* vc =[storyboard instantiateViewControllerWithIdentifier:#"MyTableVC"];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
// ensure embedded view is aligned to top
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
vc.view.frame = frame;
[vc didMoveToParentViewController:self];
}
Don't forget to specify a storyboard ID for your UITableViewController with the static cells.
I know this is an old question but I have a scrappy solution to this issue.
I needed 3 static cells on a UIViewController so this is what I did:
Drag in some Table View Cells into your interface (not into UITableView) - add text and whatever else you need.
Make IBOutlet properties for your cells and synthesise them.
Drag a button and make it cover the entire cell. Set the button to type 'Custom' so it appears invisible - repeat for all cells
Add numeric tags to your buttons
Implement the following functions. buttonDown is connected to the buttons 'Touch Down' event. buttonUp is connected to 'Touch Up Inside' AND 'Touch Up Outside'
-(IBAction)buttonDown:(id)sender {
if ([sender tag] == 1) {
myFirstCell.selected = YES;
}
else if ([sender tag] == 2) {
mySecondCell.selected = YES;
}
else if ([sender tag] == 3) {
myThirdCell.selected = YES;
}
}
-(IBAction)buttonUp:(id)sender {
myFirstCell.selected = NO;
mySecondCell.selected = NO;
myThirdCell.selected = NO;
}
You can do whatever else you like in the buttonDown event and use the button to go directly to a new view. I find this pretty useful.
I am not sure what you mean by static cells, but if you are trying to build the cells in IB, and then want to use it in your tableView, what you could do is in your cellForRowAtIndex you can call loadNibNamed passing the name of the .nib file you created for the cells as the parameter. Make sure that you have an outlet in your viewController which maps to the cell's .nib. Try exploring in these directions if that's what you are trying to achieve
You can make it dynamic and then switch of scrolling:
[yourTableName setScrollEnabled:NO];

Resources