How do I locate a UILabel in Xcode - objective-c

I am working on someone else's project and I can't for the life of me find where the text "Frame2" is used. I ran the simulator and the debugger spit out this:
Printing description of $147:
<UILabel: 0x7f7ff655a260; frame = (0 3.5; 105 21.5); text = 'Frame2'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7f7ff65586a0>
Can that printout reveal the location?

I would create a symbolic breakpoint for setTitle on UILabel and trace where it gets called. You can follow this link for instructions on how to do that: https://www.bignerdranch.com/blog/xcode-breakpoint-wizardry/

I think we should assume that this text is set in the storyboard. The simple way to deal with this is to open the storyboard as text. It is a simple XML file, and you will then easily be able to search it and find the text "Frame2".

Related

What is the simplest way to display a NSString value?

I'm trying to display a variable value to the IPhone screen. I'm using XCode and the simulator. I can use NSLog to print the output to the debug screen but I'm at a loss to understand how to get the same output to the actual screen.
What I have now in main.m.
NSString *testvalue = #"Test";
NSLog(#"Output %#\n", testvalue);
My understanding is that all display operations occur in viewcontroller.m but from what I have been reading ,it seems that the action is not as simple as creating debug output.
You'll need to put some sort of UI control on the screen with the capability of displaying text. UILabel would probably be the simplest. Then set the content of the label to the text you want to display.

ios10: viewDidLoad frame width/height not initialized correctly

Since upgrading to XCode8 GM and ios10, all of my views created via Interface Builder are not being initialized correctly until much much later than expected. This means in viewDidLoad, cellForRowAtIndexPath, viewWillAppear, etc, the frame size is set to {1000,1000} for every view. At some point they seem to correct, but its far too late.
The first problem encountered is with common rounding of corners failing across the board:
view.layer.cornerRadius = view.frame.size.width/2
Further problems are showing for anything that relies on frame size to do calculations in the code.
cellForRowAtIndexPath
For cellForRowAtIndexPath, frame size fails on initial table display, but then works fine once you scroll it. willDisplayCell:forRowAtIndexPath does not have the correct frame size either.
I've hardcoded a few values but obviously this is very bad code practice, as well as quite numerous in my projects.
Is there a way or place to get correct frame sizes?
EDIT
I've discovered that using the height/width constraint instead of frame width height is more reliable. This may add the overhead of needing lot of new IBOutlets to link the height/width constraints on items though.
For now I've created a UIView category that lets me access a View's height/width constraints directly without the IBOutlets. For minimal use the small loop shouldn't be a big deal. Results not guaranteed for IB items without the width/height constraints created yet obviously. Probably returns 0 at best for the constant, or worse. Also, if you don't have a height/width constraint and your view is sized dynamically based on leading/trailing constraints, this won't work.
-viewDidLoad appears to have correct frame size, but will often result in a visual change to the UI if you do modifications here.
UIView+WidthHeightConstraints.h
#interface UIView (WidthHeightConstraints)
-(NSLayoutConstraint*)widthConstraint;
-(NSLayoutConstraint*)heightConstraint;
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute;
#end
UIView+WidthHeightConstraints.m
#import "UIView+WidthHeightConstraints.h"
#implementation UIView (WidthHeightConstraints)
-(NSLayoutConstraint*)widthConstraint{
return [self constraintForAttribute:NSLayoutAttributeWidth];
}
-(NSLayoutConstraint*)heightConstraint {
return [self constraintForAttribute:NSLayoutAttributeHeight];
}
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute {
NSLayoutConstraint *targetConstraint = nil;
for (NSLayoutConstraint *constraint in self.constraints) {
if (constraint.firstAttribute == attribute) {
targetConstraint = constraint;
break;
}
}
return targetConstraint;
}
#end
EDIT 2
The category above has proven only partially effective. Mainly because ios appears to auto add a couple extra height/width constraint duplicates, that are of type NSContentSizeLayoutConstraint, which are actually not the same size as the normal constraint. The NSContentSizeLayoutConstraint is also a private class so I can't do isKindOfClass to filter those out. I haven't found another way to effectively test for those yet. This is annoying.
The most common issues you describe are appearing in iOS 10 only and can be solved by adding this line (if necessary):
self.view.layoutIfNeeded()
just above the code, that is responsible for changing constraint, layer.cornerRadius etc.
OR
place your code related to frames / layers into viewDidLayoutSubviews() method:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.layer.cornerRadius = self.myView.frame.size.width/2
view.clipsToBounds = true
... etc
}
We created a radar (28342777 (marked as duplicate for 28221021 but Open)) for the similar problem and the reply that we got was as below:
"Thank you for reporting the issue. Could we get more information about the profile image view? In Xcode 8, a fully constraint, non-misplaced view no longer saves out a frame to minimize diffs and support automatically update frames in IB. At runtime, these views get decoded with a placeholder size of 1000x1000, but are resolved after first layout. Could the image be assigned before initial layout, and would assigning the image to the image view after first layout address this case? Please send a sample to help us further analyze. thanks!"
At present we have provided them the sample project. My observations:
The problem that we had used to happen for XIBs that are converted from Xcode 7.x to Xcode 8.x
If we intentionally break the constraint in XIB then viewDidLoad will get expected height and width and not 1000x1000.
For us it was a UIImageView on which we were apply some layering for making it circular and using masksToBounds. If we set masksToBounds = NO then we everything was working fine.
Though Apple claims that it is going to be a standard from Xcode 8 that views will be set to 1000x1000, the behavior doesn't seem to be consistent.
Hope this helps.
I encountered the same issue and try to solve it without luck by referring above suggestions.
Seems it should be a bug for Apple to solve. I finally find a solution by changing to save my XIB document back to Xcode 7.x format and my UI back to normal.
Until Apple releasing a fix, I don't want to spend my time on hacking it.
What about doing this:
- (NSLayoutConstraint*)widthConstraint{
return [self constraintForAttribute:NSLayoutAttributeWidth];
}
- (NSLayoutConstraint*)heightConstraint {
return [self constraintForAttribute:NSLayoutAttributeHeight];
}
- (NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute {
NSLayoutConstraint *targetConstraint = nil;
for (NSLayoutConstraint *constraint in self.constraints) {
//NSLog(#"constraint: %#", constraint);
if (![constraint isKindOfClass:NSClassFromString(#"NSContentSizeLayoutConstraint")]) {
if (constraint.firstAttribute == attribute) {
targetConstraint = constraint;
break;
}
}
}
return targetConstraint;
}
You should never rely on the timing of when a view is layed out. If that worked for you before, then out of pure luck. There are very little guarantees about this in UIKit. If you rely on something adopting to the size of your view, the right thing to do is override layoutSubviews in that view and adjust your stuff there.
Even after your view is fully rendered on screen, there are still so many conditions that could cause the size of the view to change. For example: Double height status bar, multitasking on iPad, device rotation, just to name a few. So it never is a good idea to do frame related layout changes at a particular point in time.
I was having the exact same problem. I had custom UITableViewCell subclasses and was using clipsToBounds = YES and self.iconView.layer.cornerRadius = self.iconView.frame.size.width/2 to give myself a circular image. Tried calling my cell configuration method from cellForRowAtIndexPath and willDisplayCell and neither worked.
Here is what works:
Move your layering code into the cell's -layoutSubviews method like this:
-(void)layoutSubviews {
[super layoutSubviews];
self.iconView.clipsToBounds = YES;
self.iconView.layer.cornerRadius = self.iconView.frame.size.width/2;
}
After this the images should load properly and your layering code should also work.
Only Update frame in your autolayout box .

How to set initial zoom on UIWebView in xcode

I'm wondering how to set an initial zoom on a PDF document loaded in a UIWebView in XCode. It is a table, and I want the web view to load zoomed in on a specific column (or part of a column which I can then scroll up and down). I've been reading and some people have pointed to this method - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script but I don't know exactly how this works.
And while we're on the subject of PDFs, is there any way to scrape the PDF and turn it into usable strings?
Edit: For reading a pdf, PDFBox is one possible solution. You have to import JAR files into your Xcode project. Here is a tutorial: http://www.oreillynet.com/pub/a/mac/2005/01/07/ipod_reader.html
UIWebView *webV = [[UIWebView alloc] init];
webV.scrollView.zoomScale = 4.0;

Cocoa button won't display image

Just started exploring Cocoa so pretty much a total noob.
I've written a very simple game. Set it up in Interface Builder and got it working fine.
It contains a number of buttons and I'm now trying to get the buttons to display images.
To start with I'm trying to get an image displayed on just one of the buttons which is called tile0 .
The image file (it's nothing but a green square at the moment, but I'm just trying to get that working before I attempt anything more exotic) is sitting in the same directory as the class file which controls the game.
I have the following code sitting in my wakeFromNib method:
NSString *myImageFileName = [[NSString alloc] init];
myImageFileName = #"greenImage.jpg";
NSImage *myImage = [[NSImage alloc] initByReferencingFile:myImageFileName];
[tile0 setImage: myImage];
Trouble is, the game runs fine, but the image isn't appearing on my button.
Is there someone who could kindly tell me if I'm doing something obviously wrong?
Many Thanks.
The first problem is you allocate a string but then replace it with a string constant. That isn't causing your image problem but it is a memory leak.
I've never used initByReferencingFile, I usually just use imageNamed:. There is an example of using imageNamed here.

Changing an NSImage in XCode - this line of code not working

I am having a problem that is eating me alive. I really hope I am just missing something small here. It appears to be a rather "n00b" issue.
I have a blank NSImageView that I want to display a picture when a button is pressed — simple as that.
Here is my line of coding
NSBundle *mb = [NSBundle mainBundle];
NSString *fp = [mb pathForResource:#"tiles" ofType:#"PNG"];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:fp];
if ( [image isValid] ) {
[selection setImage:image];
[selection setImageScaling:NSScaleProportionally];
}
Whereas,
tiles.PNG is a resource in my bundle
and if [image isValid] is satisfied, because I've inserted dummy code into the clause and had that work
selection is defined in my header file as follows
IBOutlet NSImageView *selection;
It is also linked up to the application delegate in IB.
I have a feeling I might not be linking it properly?
WHy wouldn't the image display? If anyone can see an error - or provide me with working code - I would be soooooo thankful
Brian
It's not a linking issue—your app wouldn't even launch (assuming it even links successfully) if you'd failed to link against Cocoa or AppKit.
More probably, either you haven't connected the outlet to your image view in your nib, or you haven't loaded the nib yet. The way to check this would be to NSLog the value of the imageView pointer, using the %p formatter.
I had a similar issue where my view wasn't displaying, and it turned out that the view was hidden. This was a setting in the view properties in Interface Builder. Just a punt, but give it a go.
You need to use the debugger and see what's going on as it runs. Is fp nil? Is image nil? Is selection nil? The debugger is your friend.
did you remember to send -setNeedsDisplay to the NSImageView after you set the image?