What I would like to do is to make a custom UITextView to allow dynamically changing size and positions of it like PicLab's text edit function.
PicLab tools article
In sum for my simple questions following
1, How to move a position of TextView at your disposal
2, How to change a size of TextView by finger slide
3, How to dynamically change size of fonts corresponding to size of TextView
That would be great if sharing me with useful links as well as codes.
to move the position of a UITextView (actually of any UI element in iOS), you can modify its frame property. the frame property defines the rectangle that this elements takes on the screen, being defined with x and y positions ( (0, 0) is the top left corner of the screen).
you can also change the size of a UITextView by modifying the frame, this time instead of modifying x and y, you'll have to modify its height and width
an example of setting a UITextField with a width of 200 and height of 50 would look like in the top left corner of the screen looks like:
CGFloat x = 0.0;
CGFloat y = 0.0;
CGFloat width = 2000.0;
CGFloat height = 50.0;
textField.frame = CGRectMake(x, y, width, height)
the changing of the font size will have to be implemented dynamically by a custom function of yours, you can use the class method of UIFont fontWithName:size for this.
Frame cannot be set for coordinates and dimension directly, you have to assign a new object. A quick search found this, Change ios Frame Size(width e height) keeping position (x,y).
Related
On the iPad, the Grouped style tableview's cells are inset deeper from the edge of the tableview than on the iPhone.
I need to retrieve the Left and Right distances from the edges of the tableview to where the cell begins. What i'm referring to is similar to "Margins". I read the UITableview API up and down and can't find a property that returns this.
I need to use this in calculation to compute where to position content in my cells.
Thanks in advance!
Alex
I haven't tested this but i'm pretty sure you should just be able to pick up the frame of both and then compare from there.
CGRect cellFrame = yourCell.frame;
CGRect tableFrame = yourUITableView.frame;
The CGRect values are (x coordinate, y coordinate, width, height).
Also you can just print out the frames using :
NSLog(#"your cell frame is %#",NSStringFromCGRect(yourCell.frame);
NSLog(#"your table frame is %#",NSStringFromCGRect(yourUITableView.frame);
I solved this with overriding the layoutSubviews call for the iPad and setting the grouped view margins to what I want them to be, rather then what the apparently hidden value is. Other answers in Stack point out that it can vary from 10 to 45 pixels in width.
In your CustomTableViewCell class
- (void)layoutSubviews
{
CGRect f = self.bounds;
f = CGRectInset(f, 10, 0);
self.contentView.frame = f;
self.backgroundView.frame = f;
}
You could force it to keep contentView and backgroundView to be equal to that of the TableCell width which is that TableView width, but in this case I still wanted my grouped view to be inset a little bit. It also allows you to better match with a custom header/footer view which will go edge to edge without work.
I have multiple UIImageView's within a UIView. These UIImageViews have been transformed.
When the gesture is applied to any one of the UIImageView's the overlapping imageViews should get displaced in such a way that the move outside the UIImageView's frame and we get a full view of the image (all of this would be done in an animating manner).
Also please note that the images will have been transformed so I wont be able to use the frame properties.
Right now I'm using CGRectIntersectsRect but its not giving me the desired effect.
After struggling a lot, finally i achieved the desired result with this algorithm.
I calculate the list of overlapping UIImageView's and store it in an array.
I am using CGRectIntersectsRect for this.
Note : This will also include the UIImageView on which the gesture was applied (say target ImageView).
For each of these overlapping UIImageView, i perform the following steps :
1) Calculate the angle between the overlapping ImageView and target
ImageView. This will give me the direction to shift the Overlapping ImageView.
2) Now shift the overlapping ImageView by some constant distance(say len), such that it maintains the same angle. Direction should be such that it moves away from the target ImageView.
3) You can calculate the new x,y co-ordinates using Sin/Cos functions.
x = start_x + len * cos(angle);
y = start_y + len * sin(angle);
NOTE: For ImageViews whose center is less than your target ImageView's center, you will need to subtract the value.
4) Now shift the overlapping ImageView to the new calculated center.
5) Continue shifting it until the views do not intersect any more.
I am attaching my code. I hope it helps.
-(void)moveImage:(UIImageView *)viewToMove fromView:(UIImageView
*)imageToSendBack
{
CGFloat angle = angleBetweenLines(viewToMove.center, imageToSendBack.center);
CGFloat extraSpace = 50;
CGRect oldBounds = viewToMove.bounds;
CGPoint oldCenter = viewToMove.center;
CGPoint shiftedCenter;
while(CGRectIntersectsRect(viewToMove.frame,imageToSendBack.frame))
{
CGPoint startPoint = viewToMove.center;
shiftedCenter.x = startPoint.x - (extraSpace * cos(angle));
if(imageToSendBack.center.y < viewToMove.center.y)
shiftedCenter.y = startPoint.y + extraSpace * sin(angle);
else
shiftedCenter.y = startPoint.y - extraSpace * sin(angle);
viewToMove.center = shiftedCenter;
}
viewToMove.bounds = oldBounds;
viewToMove.center = oldCenter;
[self moveImageAnimationBegin:viewToMove toNewCenter:shiftedCenter];
}
I didn't try this, but I would do it like this:
After getting the bool from CGRectIntersectsRect, multiply this overlapping UIImageView x and y by the width and height of it.
And since you can't use frame property after changing the transformation, you will need to multiply the width and height by 1.5 for the maximum amount of rotation.
Warning: If the transform property is not the identity transform, the
value of this property is undefined and therefore should be ignored.
This might move some view father than other, but you will be certain all views will be moved outside the UIImageView's frame.
If you try it and it doesn't work, post some code and I will help you with it.
EDIT: For views that their x,y less than your UIImageView's x,y you will need to subtract the offset.
I have a UIWebView which resizes when the device is rotated. When the webview is resized the scroll position from the top of the page remains the same, but since the height of the content is changing, you end up in a different place at the end of the rotation.
The content of the webview is text and images which are not being scaled to fit. At a smaller width the text breaks more making it taller.
Is there a good way to maintain the scroll position?
One way to kind of work around this problem is to adjust the contentOffset of the webviews's scrollview after a rotation. Due to changes in line breaks in texts the overall size of the page may change during a rotation.
So to solve this, you have to save the old size of the webviews content in the "willRotateToInterfaceOrientation"-method, then calculate the relative change in the "didRotateFromInterfaceOrientation"-method and adjust the scrollviews contentOffset. (That 'almost' solve the problem - i say almost because due to the changes in line breaks, you might end up one or two lines off your desired position.)
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
oldSize = self.webView.scrollView.contentSize;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
CGSize newSize = self.webView.scrollView.contentSize;
float xFactor = newSize.width / oldSize.width;
float yFactor = newSize.height / oldSize.height;
CGPoint newOffset = webView.scrollView.contentOffset;
newOffset.x *= xFactor;
newOffset.y *= yFactor;
webView.scrollView.contentOffset = newOffset;
}
Take a look at my solution: https://github.com/cxa/WebViewContentPositioner. In short, I use document.caretRangeFromPoint(0, 0) to capture the Range, and insert an element to track its position. After resizing, use the captured Range info to decide position.
I found another question and answer explaining how to get the width, height, and position of a window using the Accessibility API. Is there any way to find the minimum size, maximum size, resize increments, etc?
Edit:
My current approach is to use AXUIElementCopyAttributeValue but I'm not sure that's possible . Looking at the reference you can see there are a lot of properties I can access, but I can't find any mention of the minimum or maximum size of the window. Note it seems position is accessible through this API.
Now I was also looking at some sample code called Son of Grab which is also able to access window size and position but I don't believe that method works for minimum or maximum size either.
As far as I can tell, there is no easy way about it. I have found one very crude method of getting the maximum and minimum size of the window.
It involves setting the width and height to a very large number to see how far the window resizes then remembering this size as the maximum, then setting the width and height to a small number and doing the same again. After all this I just reset the width and height to their original values.
The obvious problem with this is the fact that it is very visible to the user that the window has been resized.
As for the resize increments I can't think of (at the moment) any workaround to getting that information.
Anyway here's the code I have for working out the maximum and minimum size:
AXUIElementRef window; // The window
AXValueRef sizeValue = (AXValueRef)[UIElementUtilities valueOfAttribute:#"AXSize" ofUIElement:window];
CGSize windowSize;
AXValueGetValue(sizeValue, kAXValueCGSizeType, &windowSize);
CGFloat windowWidth = windowSize.width;
CGFloat windowHeight = windowSize.height;
// Set it to a very large number
[UIElementUtilities setStringValue:#"w=5000 h=5000" forAttribute:#"AXSize" ofUIElement:window];
AXValueRef maxSizeValue = (AXValueRef)[UIElementUtilities valueOfAttribute:#"AXSize" ofUIElement:window];
CGSize maxWindowSize;
AXValueGetValue(maxSizeValue, kAXValueCGSizeType, &maxWindowSize);
CGFloat maxWindowWidth = maxWindowSize.width;
CGFloat maxWindowHeight = maxWindowSize.height;
NSLog(#"max width = %f. max height = %f.", maxWindowWidth, maxWindowHeight);
// Set it to a very small number
[UIElementUtilities setStringValue:#"w=0 h=0" forAttribute:#"AXSize" ofUIElement:window];
AXValueRef minSizeValue = (AXValueRef)[UIElementUtilities valueOfAttribute:#"AXSize" ofUIElement:window];
CGSize minWindowSize;
AXValueGetValue(minSizeValue, kAXValueCGSizeType, &minWindowSize);
CGFloat minWindowWidth = minWindowSize.width;
CGFloat minWindowHeight = minWindowSize.height;
NSLog(#"min width = %f. min height = %f.", minWindowWidth, minWindowHeight);
// Reset size
[UIElementUtilities setStringValue:[NSString stringWithFormat:#"w=%f h=%f", windowWidth, windowHeight] forAttribute:#"AXSize" ofUIElement:window];
In case you were wondering, UIElementUtilities is a class I've taken from one of the Apple example projects called UIElementInspector.
I have an cocos2D app that runs in 4/3 ratio and I want to enter fullscreen mode resizing the view to maintain the aspect ratio without showing black bars at screen sides. So, when the app enters fullscreen, I do this:
NSRect aFrame=[[NSScreen mainScreen] frame];
[glView_ setFrameSize:NSMakeSize(aFrame.size.width,aFrame.size.height*1.2)];
This way I got fullscreen wide but (as I wanted) the ratio is untouched. My problem now is that the glview is not centered on screen. It extends from left bottom point so I got my game unevenly clipped (all clipping is done at top). I've trying to use [glview setFrameOrigin] and similar to select the visible portion of the view without success.
I just want to displace my view a certain number of pixels down so it shows the center area of whole view. Is it possible?.
Thanks in advice.
You are changing the dimensions of glView_, but not its origin.
NSRect aFrame=[[NSScreen mainScreen] frame];
CGFloat x = 0.0f;
CGFloat y = aFrame.size.height;
CGFloat width = aFrame.size.width;
CGFloat height = aFrame.size.height * 1.2f;
glView_.frame = NSRectFromCGRect((CGRectMake(x, y/2 - height / 2, width, height));