I have a problem that I've searched the internet for a solution for with no avail. I'm following along in chapter 10 of Apress' Beginning iOS 5 development which is on storyboards.
I'm thinking the book is missing a simple piece of code and since I'm going through this for the first time, I don't know how to resolve it.
I've restarted the project twice, but keep getting this error in the debugger:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
#import "BIDTaskListController.h"
#interface BIDTaskListController ()
#property (strong, nonatomic) NSArray *tasks;
#end
#implementation BIDTaskListController
#synthesize tasks;
- (void)viewDidLoad {
[super viewDidLoad];
self.tasks = [NSArray arrayWithObjects:
#"Walk the dog",
#"URGENT:Buy milk",
#"Clean hidden lair",
#"Invent miniature dolphins",
#"Find new henchmen",
#"Get revenge on do-gooder heroes",
#"URGENT: Fold laundry",
#"Hold entire world hostage",
#"Manicure",
nil];
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.tasks = nil;
}
//
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [tasks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = nil;
NSString *task = [self.tasks objectAtIndex:indexPath.row];
NSRange urgentRange = [task rangeOfString:#"URGENT"];
if (urgentRange.location == NSNotFound) {
identifier = #"plainCell";
} else {
identifier = #"attentionCell";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
UILabel *cellLabel = (UILabel *)[cell viewWithTag:1];
cellLabel.text = task;
return cell;
}
#end
lack of code:
...
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UILabel *label = [[UILabel alloc] initWithFrame:cell.bounds];
label.tag = 1;
[cell addSubview:label];
}
UILabel *cellLabel = (UILabel *)[cell viewWithTag:1];
cellLabel.text = task;
....
Actually, I think that your original problem isn't anything missing from the code, it's missing from your storyboard configuration! IIRC, the book describes creating two cell prototypes in the storyboard: One with red text and its identifier set to "attentionCell", and one with black text and its identifier set to "plainCell". If those two cells exist within the tableview in the storyboard, with the right identifiers set, then the original piece of code you posted should work just fine.
There is no missing code. I followed the instructions in Chapter 10 exactly, and it compiled and ran fine.
The top of page 363 explains that a table view loaded from a storyboard can create cells on demand, and there is no need to check for a nil return.
Related
I've been trying for a while now to get the tableview to work correctly. Every day I am making a bit of progress but I am not able to see any kind of feedback by testing the app so I am not sure if I am doing something correctly or not.
I've searched on google for a while, looked at apple docs, but I still don't understand how I can populate the UITableView properly.
First problem. Where do I get the cell? I need to make a custom cell to display the data. The solution seems to be using a nib, but how can I load it on another view controller?
Second problem. This cell should obviously have dynamic content. This content would be picked up from the user defaults (I am able to do that), but I have no idea how I could access the labels in the nibs to achieve this.
Third problem. I want to have different sections (each section has a different kind of cell to display), with different headers/footers. As always, here I find the documentation lacking. How can I achieve this?
Fourth, and most important problem. I have NO IDEA on how to load the cells. Apparently that is done by cellForRowAtIndexPath but I am unsure how it manages to do that.
Finally, here's the code (along with the stacktrace). Hope you can help me. Please, do not close this for duplicate. Firstly, it shouldn't be, secondly, it's not a duplicate if the duplicate question was asked 3+ years ago because of how much the libraries have been updated.
#import "profileViewController.h"
#import "../Objs/CCProfileObject.h"
#interface profileViewController ()
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (strong, nonatomic) IBOutlet UITableViewCell *proxySampleCell;
#property (strong, nonatomic) IBOutlet UITableViewCell *ccSampleCell;
#end
#implementation profileViewController
#synthesize tableView;
- (void)viewDidLoad{
// Dark mode, you can skip all of this
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(changeColor:)
name:#"darkToggle" object:nil];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults boolForKey:#"darkMode"] == YES){
[self changeColor:nil];
}
}
- (void)viewDidAppear:(BOOL)animated{
// Display profiles
NSData *arrayData = [[NSUserDefaults standardUserDefaults] objectForKey:#"profileArray"];
NSArray *profiles = [NSKeyedUnarchiver unarchiveObjectWithData:arrayData];
for(NSObject *profile in profiles){
if([profile class] == [CCProfileObject class])
{
CCProfileObject *ccProfile = (CCProfileObject*) profile;
printf("%s\n", [ccProfile.getName UTF8String]);
// Retrieve info from the object
// Duplicate cell
// Change appropriate labels
// Add cell to a specific section
}
// Different types of cells will be added later
// Concept is the same, what changes is the specific section and cell to duplicate
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.section == 1){
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"reusableShippingCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"reusableShippingCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
cell.textLabel.text = #"aldo";
return cell;
}
return nil;
}
// This should be the only part that actually works (I use the same class twice because proxy and shipping are not yet done)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
// Display profiles
NSData *arrayData = [[NSUserDefaults standardUserDefaults] objectForKey:#"profileArray"];
NSArray *profiles = [NSKeyedUnarchiver unarchiveObjectWithData:arrayData];
NSMutableArray *sectionData = [[NSMutableArray alloc]init];
for(NSObject *profile in profiles){
// Credit
if([profile class] == [CCProfileObject class])
{
[sectionData insertObject:#1 atIndex:0];
}
// Shipping
else if([profile class] == [UIImage class])
{
[sectionData insertObject:#1 atIndex:1];
}
// Proxy
else if([profile class] == [UIImage class])
{
[sectionData insertObject:#1 atIndex:2];
}
}
int toReturn = 0;
for(int i = 0; i < [sectionData count]; i++){
toReturn += [[sectionData objectAtIndex:i] integerValue];
}
return toReturn;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Credit card section
if(section == 0){
return 1;
} else if (section == 1){
return 2;
} else {
return 3;
}
}
`Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.52.10/UITableView.m:9453
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView (<UITableView: 0x16106d000; frame = (0 0; 375 812); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1d0243bd0>; layer = <CALayer: 0x1d0030f60>; contentOffset: {0, -88}; contentSize: {375, 117}; adjustedContentInset: {88, 0, 83, 0}>) failed to obtain a cell from its dataSource (<profileViewController: 0x15ff14c70>)
First throw call stack:
(0x1837f6d8c 0x1829b05ec 0x1837f6bf8 0x1841e6fa0 0x18d4975b0 0x18d4941e8 0x18d493e00 0x18d492b1c 0x18d48e668 0x18d3cb770 0x18796d25c 0x1879713ec 0x1878ddaa0 0x1879055d0 0x18d7b56b4 0x18379f2bc 0x18379ea7c 0x18379c7b0 0x1836bcda8 0x18569f020 0x18d69d78c 0x1048a4f90 0x18314dfc0)
libc++abi.dylib: terminating with uncaught exception of type NSException
You are not required to solve all of my problems with a single answer. Even fixing a problem/explaining what I need to do is enough as that will allow me to at least move a bit forward.
First, you don't need a custom nib for UITableViewCell unless you have a really complex cell. Rather than that, you can directly design your cell layout using Prototype Cells in UITableView's Attributes inspector. Just give Prototype Cells a number & design appropriate cell's layout inside UITableView view. Don't forget to set identifier for each of them, that will help you load correct layout in cellForRowAtIndexPath.
For simple cell layout, you can provide each of elements of the cell a tag number. This will help you access them whenever you need them like this:
UILabel *label = [cell viewWithTag:100];
Every UITableView needs a DataSource, you will implement UITableViewDataSource to provide:
Number of sections for your table
Number of items for each section
Content for individual cell
You just did it in your provided source code, except one thing: cellForRowAtIndexPath requires a UITableViewCell to be returned, not nil. If you return nil, exception will be thrown.
So, a working cellForRowAtIndexPath might look like this:
#implementation ViewController {
NSArray *data;
}
- (void)viewDidLoad {
[super viewDidLoad];
// You load your data from NSUserDefault here
data = [self loadDataFromNSUserDefault];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = #"defaultCell";
if (indexPath.section == 0) {
cellIdentifier = #"customCell1";
} else if (indexPath.section == 1) {
cellIdentifier = #"customCell2";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// Access your view's children using their `tag`
UILabel *title = [cell viewWithTag:100];
UIImageView *icon = [cell viewWithTag:101];
// Set content
title.text = [[data objectAtIndex:indexPath.row] objectForKey:#"title"];
icon.image = [UIImage imageNamed:[[data objectAtIndex:indexPath.row] objectForKey:#"icon"]];
return cell;
}
Your core problem lies in this line - if (indexPath.section == 1) - the section numbering starts from 0. So you return nil for cells in your first section (numbered 0), and any section beyond the second one (numbered 1), which causes the crash. You should never return nil from cellForRow.
That being said - I still recommend you read through the links provided in the comments, you may still learn something valuable and/or interesting.
I have been experiencing this event where UITableView cell contents are loaded fine on iOS 9, but not on iOS 8. I have verified this both on the simulator and on the device.
I have tried loading the data on viewDidLoad, viewWillAppear, and even in viewDidAppear but still the same. I have tried a dispatch_async to reload the the tableView but still the same.
Check the images below to see the problem I am experiencing.
However, when I tap the position for the stars, the UIView for the stars suddenly appears.
Here is my code for the UITableView controller.
#interface EvalTableViewController ()
#property (strong, nonatomic) NSDictionary *allItems;
#property (strong, nonatomic) NSArray *items;
#property (strong, nonatomic) NSMutableArray *ratings;
#end
#implementation EvalTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.estimatedRowHeight = 140.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
_allItems = [[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"AssessmentItems" ofType:#"plist"]];
_items = nil;
_items = [_allItems objectForKey:_currentEval];
[self loadRatings];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"itemCellId";
ItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
cell.item.text = _items[indexPath.row];
cell.ratingView.value = ((NSNumber *)_ratings[indexPath.row]).floatValue;
[cell bringSubviewToFront:cell.ratingView];
[cell.ratingView addTarget:self action:#selector(updateRating:) forControlEvents:UIControlEventValueChanged];
[cell layoutSubviews];
return cell;
}
- (void)updateRating:(HCSStarRatingView *)ratingView {
long indexOfRatingView = [self.tableView indexPathForCell:(ItemTableViewCell *)[[ratingView superview] superview]].row;
[_ratings replaceObjectAtIndex:indexOfRatingView withObject:[[NSNumber alloc] initWithFloat:ratingView.value]];
[self.tableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:indexOfRatingView inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}
- (void)loadRatings {
_ratings = nil;
_ratings = [[NSMutableArray alloc] init];
for (int i = 0; i < _items.count; i++) {
[_ratings addObject:[[NSNumber alloc] initWithFloat:1.0]];
}
}
}
I have not added anything on the ItemTableViewCell code. Here it is:
#implementation ItemTableViewCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
I am new on iOS app development, I hope you can help.
Thanks.
It seems that all our past efforts to solve my problem was more focused on loading the cells, and not on the UITableViewCell itself.
I have found out that the problem lies on my constraints for my label and for the star rating. I just added a height constraint to my star rating and it becomes visible when the tableView appears. I also needed to put [self.tableView reloadData]; on my viewDidAppear method.
However, the UITableViewCell displays in its fixed height initially, then adjusts it's height after the view is presented to the user which might not be appealing for the user. And the tableView scrolls when I tap the star rating.
But anyways, this gave me hope in solving my problem.
I just find it odd. Because, if it's a constraint or layout error, why does it work fine on iOS 9 and not on iOS 8?
Thanks a lot.
Try adding this code in the awakefromnib method in the tableViewCell.m file(after importing HCSStarRatingView ).Also try the debugging mode in simulator to see if the view is there before the first touch.
HCSStarRatingView *starRatingView = [[HCSStarRatingView alloc] initWithFrame:initWithFrame:CGRectMake(0, 0, self.ratingView.frame.size.width, self.ratingView.frame.size.height)];
I guess there is problem with bring subview to front may be.
please try this in cell for row at index path method .
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"itemCellId";
ItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
cell.item.text = _items[indexPath.row];
cell.ratingView.value = ((NSNumber *)_ratings[indexPath.row]).floatValue;
//[cell bringSubviewToFront:cell.ratingView];
[cell.ratingView addTarget:self action:#selector(updateRating:) forControlEvents:UIControlEventValueChanged];
[cell layoutSubviews];
return cell;
}
And if it is still not working than in view did load add this code and test again.
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.estimatedRowHeight = 140.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
_allItems = [[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"AssessmentItems" ofType:#"plist"]];
_items = nil;
_items = [_allItems objectForKey:_currentEval];
[self.tableView reloadData];
[self loadRatings];
}
Hope this will solve your problem.
After calling [self loadRatings]; , you need to reload your table data try it.
I have a regular view controller (not a table view controller) and on that view I have a tableview. My table view cells are custom and I just made them through storyboards (didn't do anything in the code) but when I run my application, the tableview is blank. Any ideas as to why tho is happening to me? I have looked at other things on here but all of these other scenarios have to do with the person using an NSArray to fill out the tableview in the code, but mine is custom so I am not doing that. Thanks for any help. And before you mark this duplicate, please actually read this.
my code is as follows:
#interface TTViewController ()
{
NSArray *messageComponents;
}
#end
#implementation TTViewController
#synthesize dateTimePicker, messageSetupTableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = #"Message Setup";
messageComponents = [[NSArray alloc] initWithObjects:#"Recipient",#"Message", #"Date",#"haha", nil];
messageSetupTableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
messageSetupTableView.alpha = 0.9;
}
#pragma mark -
#pragma mark Table view data source
-(NSInteger) numberOfSectionsInTableView:(UITableView *) tableView{
return [messageComponents count];
}
-(NSInteger)tableView:(UITableView *) tableVew numberOfRowsInSection:(NSInteger)section{
return 1;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
}
}
// Configure the cell.
cell.textLabel.text = [messageComponents objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:[messageComponents objectAtIndex:indexPath.row]];
cell.backgroundColor = [UIColor redColor];
cell.textLabel.textColor = [UIColor whiteColor];
UIColor *selectedColor = [UIColor blueColor];
UIView *myBackgroundColor = [[UIView alloc] init];
[myBackgroundColor setBackgroundColor:selectedColor];
[cell setSelectedBackgroundView:myBackgroundColor];
return cell;
I want my table view to have a date picker in one section, a textview in the other, and a button and a few text fields in the other. Thanks
A couple of suggestions:
First make sure that UITableView's delegate and datasource are mapped or not either from IB or programmatically.
Put a break point on cellForRowAtIndexPath delegate function and see if it comes in this functions, and make sure you are using this function to create your custom cells.
Double check your have at least one row in your tableView using something similar:
- (NSInteger)numberOfRowsInSection:(NSInteger)section
{
return 5; // for test pass value 5 so tableView should aware to display 5 rows.
}
Hope it helps!
I saw many other questions like this, but I didn't find the (right) answer. I've got two UITableViews on two different UIViewControllers. But the second UITableView doesn't show any rows.
Code for the second UIViewController (detail.m):
// detail.m
#import "detail.h"
#interface detail ()
#end
#implementation detail {
}
#synthesize tweetsArray;
#synthesize tableView;
#synthesize searchBar;
- (void)viewDidLoad
{
[super viewDidLoad];
//1
self.tableView.dataSource = self;
//2
self.tweetsArray = [[NSArray alloc] initWithObjects:
#"Always put your fears behind you and your dreams in front of you.",
#"A relationship with no trust is like a cell phone with no service, all you can do is play games.",
#"People should stop talking about their problem and start thinking about the solution.",
#"Dear Chuck Norris, Screw you. I can grill burgers under water. Sincerely, Spongebob Squarepants.",
#"My arms will always be open for you, they will never close, not unless you're in them.",
nil];
}
//3</pre>
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.tweetsArray count];
}
//4
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//5
static NSString *cellIdentifier = #"SettingsCell2";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//5.1 you do not need this if you have set SettingsCell as identifier in the storyboard (else you can remove the comments on this code)
//if (cell == nil)
// {
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
// }
//6
NSString *tweet = [self.tweetsArray objectAtIndex:indexPath.row];
//7
[cell.textLabel setText:tweet];
[cell.detailTextLabel setText:#"via Codigator"];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I dont see you setting the delegate for the tableview. You need to set that
self.tableView.delegate = self;
I'm using this tutorial on how to create a pop out menu.
http://www.appcoda.com/ios-programming-sidebar-navigation-menu/
I got it working when going through the tutorial, now i'm trying to implement it into my app.
I'm at the stage where i can press the menu button and the popout menu appears. The problem is, it doesn't populate itself with my table view cells.
I set the identifiers for each table view cell and then in the code reference them to full an array.
I know when woking through the tutorial, if I misspelled one of the identifiers when defining what's in the array, the program would crash. In my app, that's not the case. Hopefully that can help pin down the problem. It doesn't even change the colours which is the first part of the code.
Here's the code.
#import "SidebarViewController.h"
#import "SWRevealViewController.h"
#interface SidebarViewController ()
#property (nonatomic, strong) NSArray *menuItems;
#end
#implementation SidebarViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.2f alpha:1.0f];
self.tableView.backgroundColor = [UIColor colorWithWhite:0.2f alpha:1.0f];
self.tableView.separatorColor = [UIColor colorWithWhite:0.15f alpha:0.2f];
_menuItems = #[#"markup",#"tax"];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.menuItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [self.menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
Any help would be great.
Thanks
All you're doing is creating an array with two string literals. You must set the textlabel's text property in the following method to display the strings in table view cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [_menuItems objectAtIndexPath:indexPath.row];
return cell;
}
OMG I feel like such a noob. It turns out the ViewControler didn't have a target, hence why it wasn't responding.
I'm so sorry for wasting your time, I really feel bad now.