Use NSLayoutConstraints on a UITableView's header view - nslayoutconstraint

I am trying to add a UIView to a UITableView's header, then, using the NSLayoutConstraints I want to give it a height.
I've looked through the Apple Docs and the WWDC 2012 videos but I cannot find this particular error anywhere!
I have the following code:
- (UIImageView *)logoImageView
{
if (!_logoImageView) {
_logoImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo"]];
[_logoImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
}
return _logoImageView;
}
... in viewDidLoad
UIView *tableHeaderView = [[UIView alloc] init];
tableHeaderView.translatesAutoresizingMaskIntoConstraints = NO;
[tableHeaderView addSubview:self.logoImageView];
[self.tableView setTableHeaderView:tableHeaderView];
NSDictionary *constraintViews = #{#"tableView" : self.tableView, #"tableHeaderView" : tableHeaderView, #"logoImageView" : self.logoImageView};
[self.tableView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:[tableHeaderView(50)]"
options:0
metrics:nil
views:constraintViews]];
However when I run it I get the following error:
2012-10-08 16:31:34.559 myApp[6934:c07] *** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2372/UIView.m:5776
2012-10-08 16:31:34.561 myApp[6934:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
*** First throw call stack:
(0x199b012 0x17c0e7e 0x199ae78 0x1256f35 0x7589ef 0x17d46b0 0x622fc0 0x61733c 0x622eaf 0x7f78cd 0x7401a6 0x73ecbf 0x73ebd9 0x73de34 0x73dc6e 0x73ea29 0x741922 0x7ebfec 0x738bc4 0x738dbf 0x738f55 0x741f67 0x705fcc 0x706fab 0x718315 0x71924b 0x70acf8 0x27e8df9 0x27e8ad0 0x1910bf5 0x1910962 0x1941bb6 0x1940f44 0x1940e1b 0x7067da 0x70865c 0x6d5d 0x2395)
libc++abi.dylib: terminate called throwing an exception

I had the same exception when I was trying to set the table header view.
When I noticed that the view had Contraints I just unchecked the "Use Autolayout" option from Storyboard.
Screenshot: http://i.stack.imgur.com/5jWHy.png
This solved for me.

The best way to overcome this is to use Interface Builder to setup the UITableView header, then add an Outlet to the height NSLayoutConstraint.

Try this:
logoImageView.translatesAutoresizingMaskIntoConstraints = YES;
(If not works, try to remove:
tableHeaderView.translatesAutoresizingMaskIntoConstraints = NO; //Remove this line
:)

I didn't get any proper solution for this issue but you can fix it by using frames and not setting translatesAutoresizingMaskIntoConstraints property to No (by default its yes, so don't set it)
CGRect headerViewFrame = CGRectMake(0,0,320,60); //Frame for your header/footer view
UIView *tableHeaderView = [[UIView alloc] initWithFrame:headerViewFrame];
tableHeaderView.translatesAutoresizingMaskIntoConstraints = Yes; //Or don't set it at all
[self.tableView setTableHeaderView:tableHeaderView];

Related

SIGABRT using NSDictionary for text and shadow attributes

I'm attempting to build a simple app in Objective C, utilizing an attributes Dictionary in my AppDelegate module to allow me to customize the look of various navigation items of my story layout.
The code builds fine with no errors but as it deploys onto my test device I get a SIGABRT.
I'm using latest version Xcode(9.2); storyboards are all set to "Builds for iOS 8.2 and Later"; Deployment Target is set at 8.1.
I had utilized UITextAttributeTextShadowColor, nil in my code without issues, but that is deprecated since iOS 7.0 so I updated it to NSShadowAttributeName, nil and now it won't work.
What am I doing wrong?
The specific SIGABRT error reads: Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[UIDeviceRGBColor
shadowColor]: unrecognized selector sent to instance 0x1d447cf00'.
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *attribs = [NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:170.0/255.0 green:21.0/255.0 blue:29.0/255.0 alpha:1.0],
NSForegroundColorAttributeName,
[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0],
NSShadowAttributeName, nil];
[[UINavigationBar appearance] setTitleTextAttributes: attribs];
[[UIBarButtonItem appearance] setTitleTextAttributes: attribs forState:UIControlStateNormal];
return YES;
}
You need to do your code updation like this :
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowColor = [UIColor blackColor];
shadow.shadowOffset = CGSizeMake(1, 0);
NSDictionary * attribs = #{NSForegroundColorAttributeName: [UIColor whiteColor],
NSShadowAttributeName: shadow,
NSFontAttributeName: [UIFont titleBolder]};
[[UINavigationBar appearance] setTitleTextAttributes: attribs];
This will solve your problem of crash.
Documentation: of NSShadowAttributeName:
The value of this attribute is an NSShadow object. The default value
of this property is nil.
Clearly that's not what you do. You gave a UIColor object.
And that's exactly what is saying the error:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[UIDeviceRGBColor
shadowColor]: unrecognized selector sent to instance 0x1d447cf00'
It's saying: I tried to call a method shadowColor on a UIDeviceRGBColor (surely a cluster for UIColor) object. But since it doesn't know that method (~ selector, for your level that's the case), I crashed.
Clearly, that's where you can get suspicious. shadowColor that's an available method on NSShadow object. Maybe I did something wrong. And reading the doc you'll know it's the case.
So put a NSShadow object instead of a UIColor one for the value corresponding.

iOS7 Autolayout Issues - Adding UIView Subview to UITableViewController

I have been trying for a few hours. I am adding a subclass of UIView to the view of my UITableViewController. I am using the code at the bottom of the this post.
I get a crash that says:
2014-06-15 12:19:58.724 Block Party[4712:60b] *** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit/UIKit-2935.137/UIView.m:8794
2014-06-15 12:19:58.726 Block Party[4712:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
*** First throw call stack:
(0x2e940f0b 0x390d7ce7 0x2e940ddd 0x2f2ede2f 0x311703c5 0x30dec31b 0x30de7b3f 0x311854a1 0x3e387 0x311a5a3b 0x311bb8a5 0x3e221 0x3d267 0x31174a53 0x31174811 0x31300c13 0x3121e48f 0x3121e299 0x3121e231 0x31170305 0x30dec31b 0x30de7b3f 0x30de79d1 0x30de73e5 0x30de71f7 0x30de0f1d 0x2e90c039 0x2e9099c7 0x2e909d13 0x2e874769 0x2e87454b 0x337e16d3 0x311d3891 0x3acb5 0x395d5ab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
I attempted to resolve this by adding the layoutSublayerofLayer method but it didn't change anything. Also, if I comment out [self.locationNeededView setTranslatesAutoresizingMaskIntoConstraints:NO]; then it doesn't crash but my constraints are ignored because the autoresizingmaskconstraints take priority.
I'm totally out of ideas for how to solve this. Basically I want this view to appear on top of my table, centered horizontally and vertically.
Thanks in advance for any help you can offer.
-Jeff
- (void) layoutSublayersOfLayer:(CALayer *)layer {
[super layoutSublayersOfLayer:layer];
}
- (void)loadLocationNeededView {
UINib *nib = [UINib nibWithNibName:#"LocationNeededUIView" bundle:nil];
self.locationNeededView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
[self.locationNeededView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem: self.view
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.locationNeededView
attribute:NSLayoutAttributeCenterX
multiplier:0
constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem: self.view
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.locationNeededView
attribute:NSLayoutAttributeCenterY
multiplier:0
constant:0]];
[self.view addSubview:self.locationNeededView];
[self.view layoutSubviews];
}
Edit - Update
I gave up on using constraints and I'm just using the frame. I got it to work pretty well with the following code. I also found if I add it to the view of the navigation controller, then it won't scroll with the tableview. Which is exactly what I wanted.
- (void)loadLocationNeededView {
//allocate subview
UINib *nib = [UINib nibWithNibName:#"LocationNeededUIView" bundle:nil];
self.locationNeededView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
//set frame for it offscreen so it can be animated in
self.locationNeededView.frame = CGRectMake((self.view.frame.size.width / 2) - (self.locationNeededView.frame.size.width / 2), [[UIScreen mainScreen] bounds].size.height, self.locationNeededView.frame.size.width, self.locationNeededView.frame.size.height);
//addsubview to navigation controller so that it does not scroll with the tableview
[self.navigationController.view addSubview:self.locationNeededView];
[self animateLocationNeededViewIn];
}
- (void) animateLocationNeededViewIn {
[UIView animateWithDuration:0.35
delay:1
usingSpringWithDamping:0.7
initialSpringVelocity:1.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^ {
self.locationNeededView.frame = CGRectMake((self.view.frame.size.width / 2) - (self.locationNeededView.frame.size.width / 2), (self.view.frame.size.height / 2) - (self.locationNeededView.frame.size.height / 2), self.locationNeededView.frame.size.width, self.locationNeededView.frame.size.height);
[self.view layoutIfNeeded];} completion:^ (BOOL fin) {
if (fin) {
NSLog(#"After Animating View Frame: Origin X = %f. Origin Y = %f. Width = %f. Height = %f", self.locationNeededView.frame.origin.x, self.locationNeededView.frame.origin.y, self.locationNeededView.frame.size.width, self.locationNeededView.frame.size.height);
}
}];
}
Issues: Constraint Multipliers should be 1, not 0. also, you shouldn't need to call layoutSubviews, just call layoutIfNeeded. Also your view needs width and height constraints unless you have defined intrinsiccontentSize in your view.

UiImagePickerController doesn't crop when using setShowsCameraControls:NO

- (IBAction)showImagePickerCamera:(id)sender {
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self.picker setDelegate:self];
self.picker.allowsEditing = YES;
self.customView = [[CustomCameraViewController alloc]initWithNibName:#"CustomCameraViewController" bundle:nil];
[self.customView setCustomCameraDelegate:self];
[self presentViewController:self.picker animated:NO completion:nil];
self.needsToShowImageSource = NO;
[self performSelector:#selector(customCameraTakeAPicture) withObject:nil afterDelay:3];
[self.picker setShowsCameraControls:NO];
}
Hi all! :D I have this piece of code. I'm using setAllowsEditing:YES and setShowsCameraControls:NO. But if I set ShowsCameraControls = NO, the uiimagepickercamera doesn't allow me to crop the image.
I'm using a custom view (CustomCameraViewController) to create the buttons to take a picture, select the camera, the flash, etc. That's why i'm setting ShowsCameraControls to NO.
When I press to take a picture i'm calling
-(void)customCameraTakeAPicture
{
[self.picker setShowsCameraControls:YES];
[self.picker takePicture];
}
That takes me to the crop view but it doesn't show the square. And when i press USE the app crashes with this error :
Aug 26 04:42:50 Chad-DePues-iPod Modabound[13518] <Error>: UIImage *PLCreateCroppedImageFromImageWithQuality(UIImage *, CGRect, CGSize, CGInterpolationQuality): failed to create context
2013-08-26 04:42:50.754 Modabound[13518:861b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: object cannot be nil (key: croppedImage)'
*** First throw call stack:
(0x31c1f2a3 0x3989d97f 0x31b81313 0x36d538b7 0x36d79307 0x32535e85 0x39cf4311 0x39cf41d8)
libc++abi.dylib: terminate called throwing an exception
Any suggestions ? I've been stack for hours with this and I run out of ideas.
Thanks!

Unrecognized Selector sent to Instance in another class

I've been trying to figure out something that might be obvious and I'm missing the point or losing it. Is something wrong with my toggleStormButtons function that XCode isn't seeing it?
In my main class I have the following to call a function in another class:
STopLeftMenu *mTopLeft = [[STopLeftMenu alloc]init];
[mTopLeft drawStormToggleButton];
Then in the other class I have 2 functions:
- (void)toggleStormButtons{
[UIButton animateWithDuration:0.50 animations:^{
if (stormToggleBtn.transform.tx == 0){
[stormToggleBtn setTransform:CGAffineTransformMakeTranslation(307, 0)];
UIImage* hideButtonImg = [UIImage imageNamed:#"aiga_right_arrow_mod_hide_resize.png"];
[stormToggleBtn setBackgroundImage:hideButtonImg forState:UIControlStateNormal];
}
else{
[stormToggleBtn setTransform:CGAffineTransformMakeTranslation(0, 0)];
UIImage* showButtonImg = [UIImage imageNamed:#"aiga_right_arrow_mod_show_resize.png"];
[stormToggleBtn setBackgroundImage:showButtonImg forState:UIControlStateNormal];
}
}];
for(UIView* storm in stormButtonSaves){
[UIView animateWithDuration:0.50 animations:^{
if (storm.transform.tx == 0){
[storm setTransform:CGAffineTransformMakeTranslation(307, 0)];
storm.alpha = .65;
}
else{
[storm setTransform:CGAffineTransformMakeTranslation(0, 0)];
storm.alpha = 0;
}
}];
}
}
- (void)drawStormToggleButton{
//Storm Pullout Toggle Button
UIImage *buttonImageNormal = [UIImage imageNamed:#"aiga_right_arrow_mod_show_resize.png"];
stormToggleBtn = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 65, 75) ];
[stormToggleBtn setBackgroundImage:buttonImageNormal forState:UIControlStateNormal];
stormToggleBtn.backgroundColor = [UIColor clearColor];
stormToggleBtn.alpha = 0.5;
[stormToggleBtn addTarget:self action:#selector(toggleStormButtons) forControlEvents:UIControlEventTouchUpInside];
[viewsToRemove addObject:stormToggleBtn];
[mv addSubview:stormToggleBtn];
}
I seem to be getting an unrecognized selector message:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSMallocBlock__ toggleStormButtons]: unrecognized selector sent to instance 0x7bc9ca0'
*** First throw call stack:
(0x1b9e012 0x1966e7e 0x1c294bd 0x1b8dbbc 0x1b8d94e 0x197a705 0x8ae2c0 0x8ae258 0x96f021 0x96f57f 0x96e6e8 0x8ddcef 0x8ddf02 0x8bbd4a 0x8ad698 0x2599df9 0x2599ad0 0x1b13bf5 0x1b13962 0x1b44bb6 0x1b43f44 0x1b43e1b 0x25987e3 0x2598668 0x8aaffc 0x2285 0x2185)
libc++abi.dylib: terminate called throwing an exception
It sounds like your STopLeftMenu is being deallocated too early. The button does not retain its target, so you'll need to keep this object around as long as it needs to respond to the button's messages. If you're not sure how the object is getting deallocated, try debugging with Instruments.
I don't see anything wrong with the code you have shown. I tried it in an existing app of mine and while I had to a) declare a UIButton local variable, b) change the image used for the button and c) comment out the stuff in toggleStormButtons, the method was called every time I tapped the button, no problems.
You don't show your storage for the button. Are you using ARC? Is the button strong? If ARC it should be strong. If not ARC and you are not using a property to assign with a retain, that could cause problems.
What does viewsToRemove do? Looks like an array but it could be something else.
Why don't you use + buttonWithType: and set the frame later?

Application crashes while adding photo adding new contact

I am using ABNewPersonViewController to add new contact to the address book. Every thing is fine if I do not add any photo from photo albums. It crashes if I add any photo and here is the log:-
NSInvalidArgumentException', reason: '*** -[NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: UIImagePickerControllerOriginalImage)
What I am doing wrong, or how I can fix this problem
Thanks
This is the code I use:
mNewPersonViewController = [[[ABNewPersonViewController alloc]init]autorelease];
mNewPersonViewController.hidesBottomBarWhenPushed = YES;
mNewPersonViewController.addressBook = app.addressBook;
mNewPersonViewController.newPersonViewDelegate = self;
UINavigationController *presonNavController = [[UINavigationController alloc]initWithRootViewController:mNewPersonViewController];
self.mPopOverController = [[UIPopoverController alloc]initWithContentViewController:presonNavController ];
CGRect frame = [sender frame];
[self.mPopOverController presentPopoverFromRect:frame inView:self.view permittedArrowDirections: UIPopoverArrowDirectionUp animated:YES];
[presonNavController release];
Looks like you are trying to insert a nil value into the dictionary.