I need to make a project where I will draw some graphics on the screen, its about 25 separated bars, I've done it with UIView, but unfortunately not all devices can handle this job, because there is a 25x25 matrix of squares of UIViews, they are updating its color and alpha in 0.04 seconds, and its really takes a lot of memory to draw it like this, can someone please help with a purpose, how can it all be done faster for memory managing, and if its possible to control its components like alpha or background color for an object. Thanks in advance
What I understand is that you use 25 subviews for each bar. You can already optimize that and make each bar a single UIView. You can make a custom subclass of UIView that we will call BarView and override its drawRect method to draw the 25 squares of the bar.
Edit
Assuming you have an array bars that contains 25 bars (of type Bar). Each bar contains an array squares of 25 squares (of type Square).
- (void)drawRect:(CGRect)rect
{
CGContextRef *ctx = UIGraphicsGetCurrentContext();
for (Bar *bar in self.bars) {
for (Square *square in bar.squares) {
CGContextSetFillColorWithColor(ctx, square.color.CGColor);
CGContextFillRect(ctx, square.frame);
}
}
}
Bar and Square do not subclass UIView, they are simple NSObjects.
Finally note that this code is only an example and that there are possibilities to further improve performance.
Go for OpenGL. It has very efficient 2D drawing mechanism as well.
You might want to switch to a Core Animation based drawing approach as proposed in this answer. The idea is to draw as few things as possible using Core Graphics. Instead you create layers for all your independently animating graphical elements and animate layer properties.
To draw bars you could create a layer and set its backgroundColor and bounds/center properties to animate its size and appearance.
Related
I found out how to change the colour of constraints:
draw_options = pymunk.pygame_util.DrawOptions(screen)
draw_options.constraint_color = 200,200,200
But when drawing small objects, the size of the constraint appears to be too large and makes it look bad.
Is there a way to reduce the size of those pin joints? Instead of a radius of 5 pixels, I'd prefer 1 or 2 pixel radius joints/constraints.
An alternative was to make it partly transparent, but adding an alpha component to the colour doesn't seem to work.
draw_options.constraint_color = 200,200,200,50
Unfortunately the debug draw color for constraints doesnt work. https://github.com/viblo/pymunk/issues/160
But in general if you want special drawing its probably easiest to do it yourself. Its mainly meant for debugging and quick prototyping, so if you need more than whats included try drawing it yourself instead. There are some examples that does custom drawing and does not depend on the debug draw code.
I want to add multiple columns in UITableView. I have created one CustomeTableCell with two lines used - (void)drawRect:(CGRect)rect method. But, i able to draw only 2 lines (3 columns). I have to draw multiple lines (Vertically),Eg: 5 - 10 columns. How can draw multiple lines in tableviewcell. Can you please suggest me any idea/sample code to complete this? Thanks in advance.
What about making the backgroundColor black. Adding x white subviews to the contentView of the cell, with a 1px margin between them?
This would create the desired column look, and also add the benefit of being able to acces the columns easily, if the views were set as properties.
I had the same issue. I took a UIView and set one image of 4X2 as its background and set the frame of uiview as CGRectMake(0, 40, 330, 2). and then added the UIview in cell
[cell addSubview:uiviewwithImage];
Hope this method helps you. Thanks.
Instead of actually drawing on the tableView try layer.border properties on the subviews of the cell.
This solves the issue if the subview edge & the grid line you want to draw have same X or Y coordinate.
If you want a margin between the subview & the grid line this may not work.
I want to implement below chart like structure.
Explanation:
1. Each block should be clickable.
2. If the block is selected, it will be highlighted(i.e. Red block in figure).
I initially google for this but was unable to find. What should be "Drawing logic" corresponding to this with animation?Thanx in advance.
I think you need to use MCSegmentedControl.
You can get it from here.
Generally speaking, I'd have an image for the outline with a transparent middle, then dynamically create colored blocks behind it of the appropriate colors, with dynamic labels. The highlighting is a little tricky, but could be done with a set of image overlays. One could also try to shrink and expand fixed images for the bars/highlighting, but iPhone scales images poorly.
(Will it always be 4 blocks? There are a couple of other ways to manage it using fixed-size images overlaying each other.)
Maybe you should look into using CALayer for this?
U need to implement this type of logic using button. Just scale button width according to percentage.
And to make round rect button like appearance use the code below and don't forget to import quartz-core framework in class file.
And to scale first and last button as you need some overlap from nearby button.
btn.layer.cornerRadius = 8.0;
btn.layer.borderWidth = 0.5;
btn.layer.borderColor = [[UIColor blackColor] CGColor];
In viewDidLoad, I can create a gradient with no problem:
CAGradientLayer *blueGradient = [[CAGradientLayer layer] retain];
blueGradient.frame = CGRectMake(gradientStartX,gradientStartY,gradientWidth,gradientHeight);
where gradientWith is device-defined as 320 or 1024 as appropriate.
What I can’t do is resize it inside willRotateToInterfaceOrientation: -– and thus get rid of that empty black space off to the right -- after the user changes to landscape mode. (The nav bar and tab bar behave nicely.)
(1) Recalibrating the gradient’s new dimensions according to the new mid-point, (2) using kCALayerMaxXMargin, and (3) employing bounds all looked like they would do the job. bounds looked a litte more intuitive, so I tried that.
I don’t want to admit that I have made zero progress.
I will say that I’ve been reduced to the brute force method of trying every permutation of self, view, layer, bounds, blueGradient, and CGRect(gradientStartX,gradientStartY,newGradientWidth,newGradientHeight) with zero success.
This is not difficult. My lack of understanding is making it difficult. Anyone out there “Been there, done that”?
Does the layer resize its size automatically? If so, simple
[blueGradient setNeedsDisplay];
should do the trick.
Hope this was helpful,
Paul
I am looking for an efficient way to handle the image/frame detection from touch methods. Let's say i am building a keyboard or similar to this. I have 'n' number of images placed on the UI. When someone touches an alphabet (which is an image), i can do the following to detect the corresponding letter
1) CGRectIntersectsRect(..,..) : if i use this, then i need to check each & every letter to find out what letter exists at that touch point (let's say 100,100). This becomes O(n). If i move my finger accross the screen, then i will get m points & all corresponding image detection becomes O(n*m) which is not good.
2) Other way is building a hash for each & every x,y position so that the look up will be simply O(1). But again this will be a memory constraint as i need to store 300*300 ( assuming i am using 300*300 screen size). if i reshuffle my letters, then everything needs to calculated again. So this is not good
In other words, i need some thing like , given a point (x,y), i need some way of finding which rectangle is covering that point efficiently.
Sorry for long post & any help would be grateful.
Thanks
If there are in a regular grid, then integer division by the grid size. Assuming you've a small, fixed screen size, a bucket array gives as similar gain ( a 2D grid, where each entry is a list of the rectangles which intersect that part of the grid ) is very fast if tuned correctly so the lists only have a few members. For unbounded or large spaces, KD trees can be used.
It's useful to have the rects you want as final targets set up as subviews as a larger UIView (or subclass) where you expect all these related hits to occur. For example, if you're building your own keyboard, you could add a bunch of UIButton objects as subviews and hit test those.
So, the easy and traditional way of hit testing a bunch of subviews is to simply have code triggered by someone hitting those buttons. For example, you could add the subviews as UIControl objects (which is a subclass of UIView that adds some useful methods for catching user touch events), and call addTarget:action:forControlEvents: to specify some method to be triggered when the user does something in the rect of that UIControl. For example, you can catch things like UIControlEventTouchDown or UIControlEventTouchDragEnter. You can read the complete list in the UIControl class reference.
Now, it sounds like you might be going for something even more customized. If you really want to start with a random (x,y) coordinate and know which rect it's in, you can also use the hitTest:withEvent: method of UIView. This method takes a point in a view, and finds the most detailed (lowest in the hierarchy) subview which contains that point.
If you want to use these subviews purely for hit testing and not for displaying, then you can set their background color to [UIColor clearColor], but don't hide them (i.e. set the hidden property to YES), disable user interaction with them (via the userInteractionEnabled BOOL property), or set the alpha below 0.1, since any of those things will cause the hitTest:withEvent: method to skip over that subview. But you can still use an invisible subview with this method call, as long as it meets these criteria.
Look at UIView's tag property. If your images are in UIViews or subviews of UIView, then you can set each tag and use the tag to look up in an array.
If not, then you can improve the speed by dividing your array of rectangles into sets that fit into larger rectangles. Test the outer rectangles first, then the inner rectangles. 25 rectangles would need only 10 tests worst case as 5 sets of 5.
Thanks Pete Kirkham & Tyler for your answers which are really helpful. Lets say i dont wanna use buttons as i am mainly displaying images as a small rectangles. To check for the rect # (x,y) , i can trigger that easily by making my grid as a square & finding
gridcolumn = Math.floor(pos.x / cellwidth); gridrow = Math.floor(pos.y / cellheight);
But my problem is with touchesMoved. Lets say i started # grid-1 & dragged till grid-9 (in a 3*3 matrix), in this case, i am assuming i will get 100-300 (x,y) positions, so everytime i need to run above formula to determine corresponding grid. This results in 300 calculations which might effect the performance.
So when i display an image as a rect, can i associate some id for that image? so that i can simply just save the ids in a list (from grid-1 to grid-9) so that i can avoid the above calculation.
Thanks for your help