I have a code but in this code there is an error and I don't know Why i has this error.
I put this code because i want my ball hit least the border soy the screens.
You can see my code :
CGPoint ballCenter = ball.center;
CGRect ballRect = CGRectMake(50, 73, 50, 50); // an arbitrary location for the ball, you would normally use the frame property of the ball here
CGRect s = [UIScreen mainScreen].bounds;
CGRect adjustedScreenRect = CGRectMake(s.x-50 // take the ball's (width or height) and divide it by two to get the distance to the center. Then multiply it by two and subtract from the appropriate dimension(x offset (width), y offset (height), width (width), height (height)).
BOOL isOnScreen = CGRectContainsPoint(adjutedScreenRect, ballCenter);
// do whatever with the BOOL from the above line...
I have an error at this line:
CGRect adjustedScreenRect = CGRectMake(s.x-50 // take the ball's (width or height) and divide it by two to get the distance to the center. Then multiply it by two and subtract from the appropriate dimension(x offset (width), y offset (height), width (width), height (height)).
BOOL isOnScreen = CGRectContainsPoint(adjutedScreenRect, ballCenter);
And the error is "no member named "x" in struct CGRect".
thanks you for your help
The answer is CGRect adjustedScreenRect = CGRectMake(s.origin.x-50
BOOL isOnScreen = CGRectContainsPoint(adjutedScreenRect, ballCenter);
But I have an error Expected ) on BOOL .
Can you help me
I think you mean s.origin.x, not s.x. Because CGRect is a struct of a CGPoint and a CGSize, directly accessing the x value of a CGRect is not possible without specifying which part of the struct you want to access first.
Edit:
You never actually closed the parenthesis, or satisfied all 4 arguments, of the CGRect. Try this:
CGRectMake(s.origin.x-50, s.origin.y, width,height);
Related
According to my understanding, frame is a view's location and size using the parent view's coordinate system, bounds is a view's location and size using its own coordinate system, which means childView.convert(childView.bounds, to: parentView) should be equal to childView.frame.
But I have found this is not the case for UIPickerTableViewWrapperCell, as you can see from the picture, the frame is (origin = (x = 0, y = 160032.44775782057), size = (width = 134, height = 30.248210824676789)), and the convert(bounds, to: parentView) is (origin = (x = -71.984082796011151, y = 160032.44585526528), size = (width = 134.04199076956854, height = 29.70736933068838))
Why these two values are different?
With a little bit of digging around, I've located an instructive article that may help you understand why this seeming discrepancy is occurring.
For the sake of avoiding a broken link in the future, I'll add the scenario below.
The author begins by taking an example rectangle drawn on the screen. They print out the frame and bounds values with the following function:
private func printAll() {
print("=========================")
print("X : ", self.orangeView.frame.origin.x)
print("Y : ", self.orangeView.frame.origin.y)
print("width : ", self.orangeView.frame.size.width)
print("height : ", self.orangeView.frame.size.height)
print("=========================")
print("X : ", self.orangeView.bounds.origin.x)
print("Y : ", self.orangeView.bounds.origin.y)
print("width : ", self.orangeView.bounds.size.width)
print("height : ", self.orangeView.bounds.size.height)
print("=========================")
}
Using this, they initially begin with an equal width and height:
=========================
X : 87.0
Y : 384.0
width : 240.0
height : 128.0
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
They then perform a transformation on the rectangle to rotate it:
self.orangeView.transform = CGAffineTransform(rotationAngle: 5)
This, of course, results in the height and width of the element changing within the parent (.frame) scope:
=========================
X : 111.58938416597198
Y : 314.7747071707769
width : 190.82123166805604
height : 266.45058565844624
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
The reason for this, of course, is that by rotating the drawn rectangle, the framing rectangle has changed in size, even though the drawn rectangle has not changed dimensions. Apple is also fully aware of this as indicated in their documentation, stating the following:
Warning
If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
This is important because we can infer some important behavior from the data you've provided. Specifically, if we ignore the coordinates and instead look at the height and width values, we see the following differences:
frame: (width = 134, height = 30.248210824676789)
bounds: (width = 134, height = 32)
convert: (width = 134.04199076956854, height = 29.70736933068838)
Looking at the UI element itself in the image, we even see text that is being "squished" vertically, indicating that these elements are most likely having transforms applied in some manner. This can result in the the aforementioned undefined behavior indicated in Apple's documentation. And as Apple has indicated in their documentation, when the transform property is not the identity transform, the property's value should be ignored.
Unfortunately we cannot verify that this is the cause of the problem as UIKit, as far as I can tell from digging around, does not share the source code for it, but transforms causing undefined behavior seems like the best explanation we can reasonably arrive at.
In SpriteKit, I can use touch locatons to record "Hits" in a target, where center of the target, "bulls eye" have the coordinates (0,0). After plenty of shooting, I will fetch all hits as an array with CGPoints. Since the target is 500 x 500 points (SKScene, sks-file), all hits can have a x position from -250 to +250 and likewise for y position.
In the attatched photo, the hits are registered as points at around (150, 150).
The problem arises when I will use the famous LFHeatMap https://github.com/gpolak/LFHeatMap.
+ (UIImage *)heatMapWithRect:(CGRect)rect
boost:(float)boost
points:(NSArray *)points
weights:(NSArray *)weights;
The LFHeatMap generates a UIImage based on the array, which I add to a UIImageView. The problem is that the UIViews has the x and y values arranged differently from SKScenes
func setHeatMap() {
let points = getPointsFromCoreData()
let weigths = getWeightsFromCoreData()
var rect = CGRectMake(0, 0, 500, 500)
rect.origin = CGPointMake(-250, -250)
let image =
LFHeatMap.heatMapWithRect(rect, boost: 1, points: points, weights: weights)
heatMapView.contentMode = UIViewContentMode.ScaleAspectFit
heatMapView.image = image
}
Lowering the shots makes the heat move higher.
How can I solve this? Either All points have to be converted to fit another coordinate system, or the coordiate of the CGrect making the heatmap, must be changed. How can this be done?
This was embarrasingly easy when the solution first occured.
Run a loop trough the points array, and multiply the point.y with -1...
Then all the valus on the y-axis is correct.
I was writing a program in swift and just now I noticed that I can directly access a CGRect frame's width and height properties directly without using the CGSize width and height. That is I am now able to write a code like this.
#IBOutlet var myView: UIView!
override func viewDidLoad()
{
super.viewDidLoad()
var height = myView.frame.height
var height1 = myView.frame.size.height
}
In Objective C, when I tried to write the same code, the line height = view.frame.height is throwing an error. Can anyone please tell me the difference(if any) in these two lines of code.
I just looked into the CGRect structure reference. In Swift there is an extension defined which have members height and width. Please have a look at the code below
struct CGRect {
var origin: CGPoint
var size: CGSize
}
extension CGRect {
...
var width: CGFloat { get }
var height: CGFloat { get }
...
}
So that you can directly fetch height and width values from a CGRect. As you can see these are only getters, so you will get an error if you try to set these values using view.frame.height = someValue
frame is of CGRect structure, apart from its width and height have only getters, they can only be positive. From the documentation:
Regardless of whether the height is stored in the CGRect data structure as a positive or negative number, this function returns the height as if the rectangle were standardized. That is, the result is never a negative number.
However, size is of CGSize structure, from the documentation:
A CGSize structure is sometimes used to represent a distance vector, rather than a physical size. As a vector, its values can be negative. To normalize a CGRect structure so that its size is represented by positive values, call the standardized function.
So the difference is obvious.
In Objective C, when I tried to write the same code, the line height = view.frame.height is throwing an error. Can anyone please tell me the difference (if any) in these two lines of code.
CGGeometry.h defines a couple of types, among them the C struct CGRect. This struct has two members: origin and size.
That's all you can access in C (and Objective-C) using dot notation. Neither C nor Objective-C offer extensions for structs.
Swift imports the type as a Swift struct. The difference is that Swift does allow for extensions on structs. So it exposes several free C functions as extensions:
CGRectGetMinX() — CGRect.minX
CGRectGetMidX() — CGRect.midX
CGRectGetMaxX() — CGRect.maxX
CGRectGetWidth() — CGRect.width
[... same for y]
These C functions are there since ages—they just live in a dusty corner of CoreGraphics.
They are quite useful but you have to know their semantics (which differ a bit from the standard accessors): They normalise the dimensions.
This means that they convert a rect with negative width or height to a rect that covers the same area with positive size and offset origin.
let rect = CGRect(x: 0, y: 0, width: 10, height: -10)
assert(rect.width == rect.size.width) // OK
assert(rect.height == rect.size.height) // boom
I am trying to experiment with UIViews on screen and using pan gestures. So I got some open source code from another project that I am looking at - and trying to learn a few things from it.
-(BOOL)isPointContainedWithinBezelRect:(CGPoint)point {
CGRect leftBezelRect;
CGRect tempRect;
CGFloat bezelWidth = 20;
CGRectDivide(self.view.bounds, &leftBezelRect, &tempRect, bezelWidth, CGRectMinXEdge);
return CGRectContainsPoint(leftBezelRect, point);
}
I understand that CGRectDivide function "Slices up a rect", but thats as far as I can make out.
I hope to get more clarification regarding the function. Also, how does the function return value vide a false / true value?
void CGRectDivide(
CGRect rect,
CGRect *slice,
CGRect *remainder,
CGFloat amount,
CGRectEdge edge
)
The CGRectDivide method splits a CGRect into two CGRects based on the CGRectEdge and distance from the rectangle side amount provided to the method.
Source
You should check
https://developer.apple.com/library/ios/documentation/graphicsimaging/reference/CGGeometry/Reference/reference.html#//apple_ref/c/func/CGRectDivide
and
http://nshipster.com/cggeometry/
But it seems that this method could be simplified to
-(BOOL)isPointContainedWithinBezelRect:(CGPoint)point {
CGRect leftBezelRect = self.view.bounds;
leftBezelRect.size.width = 20;
return CGRectContainsPoint(leftBezelRect, point);
}
or even to
-(BOOL)isPointContainedWithinBezelRect:(CGPoint)point {
return CGRectContainsPoint(self.view.bounds, point) && (point.x <= 20);
}
I don't understand mapRectThatFits in the slightest. Here is a simple line of code:
MKMapRect zoomRectNorm = [mapView mapRectThatFits:zoomRect];
// BREAKPOINT HERE
Now lets look at the debugger.
Print zoomRect:
(lldb) p zoomRect
(MKMapRect) $1 = {
(MKMapPoint) origin = {
(double) x = 4.2997e+07
(double) y = 9.36865e+07
}
(MKMapSize) size = {
(double) width = 26493.1
(double) height = 148685
}
}
Print zoomRectNorm:
(lldb) p zoomRectNorm
(MKMapRect) $2 = {
(MKMapPoint) origin = {
(double) x = 4.29283e+07
(double) y = 9.36379e+07
}
(MKMapSize) size = {
(double) width = 163840
(double) height = 245760
}
}
So it adjusted the aspect ratio to 2:3 but it did not maintain the width, the height, or the origin!?
According to the documentation it should return:
A map rectangle that is still centered on the same point of the map
but whose width and height are adjusted to fit in the map view’s
frame.
Whats the deal? I would expect it to maintain the origin (as stated in the docs) and at least one of the width/height?
MapRect that fits will zoom out until it hits a zoom level that can contain your region do that the tiles are displayed in their native resolution.
It gives you back the map rect that you would get if you used setVisibleMapRect on the mapview. The center should be the same. The origin probably won't. You'll have to think about the difference between origin and center to understand why. The other thing to understand is that, although you ask for a specific map rect to be set, the mapview will always set its own idea of what is best. Its idea of what is best is the one that allows it to display tiles without zooming in or out.