I am using this tutorial http://www.raywenderlich.com/1768/uiview-tutorial-for-ios-how-to-make-a-custom-uiview-in-ios-5-a-5-star-rating-view for custom rating-bar. but I am not able to give half rating. I am trying to display half star when user touch on imageview. Please suggest me
Finally I fixed half-star problem.
if (!self.editable) return;
//The rating starts out as 0 and then builds from there.
CGFloat newRating = 0;
//loop through the image collection backwards so if it exits the loop it will have identified the MAX
for(int i = self.imageViews.count - 1; i >= 0; i--) {
UIImageView *imageView = [self.imageViews objectAtIndex:i];
CGFloat distance = touchLocation.x - imageView.frame.origin.x;
CGFloat frameWidth = imageView.frame.size.width;
if (distance <= 0){
//this means that the click was to the left of the frame
continue;
}
if (distance /frameWidth >.75) {
//If this ratio is >.75 then you are to the right 3/4 of the image or past th image
newRating = i + 1;
break;
} else {
//you didn't drop out or mark the entire star, so mark it half.
newRating = i + 0.5;
break;
}
}
self.rating = newRating;
Related
I've been building a platformer game with sprite kit, and I've ran into an issue when attempting to change the size of my player spritenode to better match the art. I am using this algorithm from a Ray Weinderlich tutorial in conjunction with JSTileMap.
- (void)checkForAndResolveCollisionsForPlayer:(Player *)player forLayer:(TMXLayer *)layer
{
NSInteger indices[8] = {7, 1, 3, 5, 0, 2, 6, 8};
player.onGround = NO; ////Here
for (NSUInteger i = 0; i < 8; i++) {
NSInteger tileIndex = indices[i];
CGRect playerRect = [player collisionBoundingBox];
CGPoint playerCoord = [layer coordForPoint:player.desiredPosition];
NSInteger tileColumn = tileIndex % 3;
NSInteger tileRow = tileIndex / 3;
CGPoint tileCoord = CGPointMake(playerCoord.x + (tileColumn - 1), playerCoord.y + (tileRow - 1));
NSInteger gid = [self tileGIDAtTileCoord:tileCoord forLayer:layer];
if (gid != 0) {
CGRect tileRect = [self tileRectFromTileCoords:tileCoord];
//NSLog(#"GID %ld, Tile Coord %#, Tile Rect %#, player rect %#", (long)gid, NSStringFromCGPoint(tileCoord), NSStringFromCGRect(tileRect), NSStringFromCGRect(playerRect));
//1
if (CGRectIntersectsRect(playerRect, tileRect)) {
CGRect intersection = CGRectIntersection(playerRect, tileRect);
//2
if (tileIndex == 7) {
//tile is directly below Koala
player.desiredPosition = CGPointMake(player.desiredPosition.x, player.desiredPosition.y + intersection.size.height);
player.velocity = CGPointMake(player.velocity.x, 0.0); ////Here
player.onGround = YES; ////Here
} else if (tileIndex == 1) {
//tile is directly above Koala
player.desiredPosition = CGPointMake(player.desiredPosition.x, player.desiredPosition.y - intersection.size.height);
} else if (tileIndex == 3) {
//tile is left of Koala
player.desiredPosition = CGPointMake(player.desiredPosition.x + intersection.size.width, player.desiredPosition.y);
} else if (tileIndex == 5) {
//tile is right of Koala
player.desiredPosition = CGPointMake(player.desiredPosition.x - intersection.size.width, player.desiredPosition.y);
//3
} else {
if (intersection.size.width > intersection.size.height) {
//tile is diagonal, but resolving collision vertically
//4
player.velocity = CGPointMake(player.velocity.x, 0.0); ////Here
float intersectionHeight;
if (tileIndex > 4) {
intersectionHeight = intersection.size.height;
player.onGround = YES; ////Here
} else {
intersectionHeight = -intersection.size.height;
}
player.desiredPosition = CGPointMake(player.desiredPosition.x, player.desiredPosition.y + intersection.size.height );
} else {
//tile is diagonal, but resolving horizontally
float intersectionWidth;
if (tileIndex == 6 || tileIndex == 0) {
intersectionWidth = intersection.size.width;
} else {
intersectionWidth = -intersection.size.width;
}
//5
player.desiredPosition = CGPointMake(player.desiredPosition.x + intersectionWidth, player.desiredPosition.y);
}
}
}
}
}
//6
player.position = player.desiredPosition;
}
I am just wondering if there is a more efficient way, or a different algorithm to handle tile collisions of this nature (contact with tiles surrounding the player) that will take into account if my player's sprite is resized to be larger. As it is, if I resize my sprite to be taller than two tile heights or two tile widths, since the tiles are 16px by 16px, it causes the entire tile collision to break down due to it using a 3 by 3 grid to handle tile collisions. My goal is to be able to handle tile collisions without having to add physicsbodies to every "wall" tile, and have the algorithm function independently of the players size. Or at least be able to choose the option with the least performance overhead. I've been thinking and researching tile collision for a few weeks and those are the only two options I have seen function. Thank you everyone for the input in advance, please let me know if any more information is necessary.
I have a view which needs to be cropped. I have 4 views displaying video sub viewed on the main view. Because of the videos ratio, I need to crop the views making the videos squares instead of rectangles. Here is my code:
- (void)videoSize {
CGFloat size;
if ([self.videosView frame].size.height <= [self.emplacementView frame].size.width) {
size = [self.emplacementView frame].size.height;
} else {
size = [self.emplacementView frame].size.width;
}
CGFloat offsetX = 0;
CGFloat offsetY = 0;
NSArray* keys = [mediaStreams allKeys];
int count = keys.count;
if ( !count ) return;
for (int i=0; i<count; i++) {
NSString* id = keys[i];
MediaStream* ms = [ mediaStreams valueForKey:id ];
switch (i) {
case 0:
offsetX = 0;
offsetY = 0;
break;
case 1:
offsetX = size / 2;
offsetY = 0;
break;
case 2:
offsetX = 0;
offsetY = size / 2;
break;
case 3:
offsetX = size / 2;
offsetY = size / 2;
break;
default:
break;
}
CGRect frame = CGRectMake(offsetX, offsetY, size / 2, size / 2);
[ms getVideoView].getView.frame = frame;
[ms getVideoView].getView.backgroundColor = [UIColor greenColor];
}
[self.videosView addSubview:[ [ mediaStream getVideoView ] getView] ];
}
I tried different ways by adding more views to hide them, but it doesn't work at all. If you already have a solution to this problem or an idea to solve it.
Set clipsToBounds property for each of the 4 views displaying video to YES
view1.clipsToBounds = YES;
I don't know is that topic had asked before, but I do some search before asking this simple question, something like "UICollectionView cycling cells" "UIColloectionView Infinite Loop".
If the post is duplicated, I am sorry for that...
I had a Horizontal Collection View as a slider in my app, 5 image will be shown, how can I set the function when user scroll to the end (the fifth Items) and slide to right and move to the first cells? also, if the user scroll the first item and slide to left, it will show the fifth item? Thanks.
SDK: iOS 7
Thank alot~
I had wrote a stupid program to control this
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = _sliderCV.frame.size.width;
self.pageControl.currentPage = _sliderCV.contentOffset.x / pageWidth;
NSLog(#"%f", _sliderCV.contentOffset.x);
CGFloat firstSlide = 0.f;
CGFloat lastSlide = pageWidth * 4;
NSLog(#"contentOffset = %f, firstSlide = %f, SelFirstCount = %li",_sliderCV.contentOffset.x, firstSlide, (long)selFirstCount);
if (_sliderCV.contentOffset.x == firstSlide) {
if (selFirstCount == 0) {
selFirstCount += 1 ;
NSLog(#"%li", (long)selFirstCount);
} else {
NSLog(#"Move to Last");
[_sliderCV setContentOffset:CGPointMake(lastSlide, 0) animated:YES];
selFirstCount = 0;
self.pageControl.currentPage = 4;
selLastCount = 1;
}
} else if (_sliderCV.contentOffset.x == lastSlide) {
if (selLastCount == 0) {
selLastCount += 1;
} else {
[_sliderCV setContentOffset:CGPointMake(firstSlide,0) animated:YES];
selLastCount = 0;
self.pageControl.currentPage = 0;
selFirstCount = 1;
}
} else {
NSLog(#"Clear");
selFirstCount = 0;
selLastCount = 0;
}
}
I have a problem with images in a scrollview. I want to scroll the images and they should be centered. There is a problem because each picture has other values in the width.
I tried it with subclassing the scrollview and, but i don't know how to get the actual image in the layoutSubviews-Method.
Status-Update:
Now i try it with scrollViewDidScroll:. But it don't stop on the next image, when i scroll fast.
The method
In arrayWithXValues stands the values where the image begins in scrollview.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGSize iOSDeviceScreenSize = [[UIScreen mainScreen] bounds].size;
float middleOfScreenX = scrollView.contentOffset.x + iOSDeviceScreenSize.width / 2;
for (int i = 1; i < 19; i++) {
if (i < 17) {
if (middleOfScreenX > [[arrayWithXValues objectAtIndex:i] floatValue] && middleOfScreenX < [[arrayWithXValues objectAtIndex:i + 1] floatValue] && actualPage != i) {
...
actualPage = i;
[self killScroll];
}
} else {
if (valMiddleX > [[arrayWithXValues objectAtIndex:i] floatValue]) {
...
actualPage = i;
[self killScroll];
}
}
}
}
- (void)killScroll {
self.horizontalScrollView.scrollEnabled = NO;
self.horizontalScrollView.scrollEnabled = YES;
}
Thanks for all your help
I'm developing a simple application that animates an image as the user moves a slider. This could easily be done with individual images, but for obvious reasons that method is inefficient.
Currently, I have the animation broken up into 14 sprite sheets with 16 images per sheet. I created a method that uses CGImageCreateWithImageInRect to find the current image dictated by the slider and update the image view with that image. This works, but not fluidly. I think I understand why, but I have no clue what to do otherwise. While I could use Cocos2d or OpenGL ES, I am stubborn and convinced that this is possible without them. I just want to know how.
Here's some example code:
- (void)setUp{
NSString *string;
NSString *bundleString = [[NSBundle mainBundle] bundlePath];
dsRedPathArray = [[NSMutableArray alloc] initWithCapacity:15];
for (int i = 0; i < 14; i++)
{
string = [bundleString stringByAppendingFormat:#"/dsRedAni_%d.png", i];
[dsRedPathArray addObject:string];
}
//initial image starts at (0, 1) of image dsRedAni_9
currentImage = [UIImage imageWithContentsOfFile:[dsRedPathArray objectAtIndex:9]];
currentRef = CGImageCreateWithImageInRect(currentImage.CGImage, CGRectMake(495, 0, kModelWidth, kModelHeight));
modelView.image = [UIImage imageWithCGImage:currentRef];
}
- (IBAction)sliderMoved:(UISlider*)sender
{
[self animateModel:sender.value];
}
- (void)animateModel:(int)index
{
index += 1;
imageIndex = (index / 16) + 9;
if (imageIndex > 13)
{
imageIndex = -14 + imageIndex;
}
currentX = kModelWidth * (index % 4);
currentY = kModelHeight * ((index / 4) % 4);
currentRect = CGRectMake(currentX, currentY, kModelWidth, kModelHeight);
currentImage = [UIImage imageWithContentsOfFile:[dsRedPathArray objectAtIndex: (imageIndex)]];
currentRef = CGImageCreateWithImageInRect(currentImage.CGImage, currentRect);
modelView.image = [UIImage imageWithCGImage:currentRef];
}
Thanks in advance for any help.
I finally found a rather quick and efficient, if unconventional, way of cycling through each section of my sprite sheets without any outside help from APIs. Rather than spending time and power cutting up the image into contexts or individual files, I found that it was more efficient for me to create a UIView in the size of the image I needed and then adding the entire sprite sheet to the view as a UIImageView.
With view.clipsToBounds set to YES, the view acts as a mask for my sprite sheet, limiting the visible portion to the size of each image I want to cycle through on the sheet. In order to give the effect of animation, I simply use imageview.center to move the sprite sheet around the view to the desired image coordinates. So, in a sprite-sheet with 16 images I only have to make one call to show the image, then move it around per each frame in the animation.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setUp];
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
}
return self;
}
- (void)setUp
{
//assign |lastImageIndex| a number not equal to |imageIndex|
lastImageIndex = -1;
modelImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 1924, 1708)];
NSString *string;
NSString *bundleString = [[NSBundle mainBundle] bundlePath];
UIImage *image;
if (!imageArray)
{
imageArray = [[NSMutableArray alloc] init];
NSLog(#"Init egfp |imageArray|");
}
for (int i = 0; i < 10; i++)
{
string = [bundleString stringByAppendingFormat:#"/moleculeAni_%d.png", i];
image = [UIImage imageWithContentsOfFile:string];
[imageArray addObject:image];
if (i == 9)
{
NSLog(#"Filled egfp |imageCache|");
}
}
[self addSubview:modelImageView];
}
- (void)animateModel:(int)index
{
if (index != 1)
{
index -= 1;
}
imageIndex = (index / 16);
if (imageIndex < 9)
{
currentX = 962 - (481 * (index % 4));
currentY = 854 - (427 * ((index / 4) % 4));
}
else
{
currentX = 962 - (481 * (index % 4));
currentY = 427 - (427 * ((index / 4) % 4));
}
if (imageIndex != lastImageIndex)
{
if (imageIndex < 9 && onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 1708);
onLastFrame = NO;
}
else if (imageIndex == 9 && !onLastFrame)
{
modelImageView.frame = CGRectMake(0, 0, 1924, 854);
onLastFrame = YES;
}
NSLog(#"Image: %d", imageIndex);
tempImage = [imageArray objectAtIndex:imageIndex];
modelImageView.image = tempImage;
}
modelImageView.center = CGPointMake(currentX, currentY);
lastImageIndex = imageIndex;
}
Most of the code here is spent determining where the imageview needs to move in order to display the correct image. This is taking the method I explained above and is spreading it across 10 sprite sheets each with 16 images spread evenly (except the last which has 8). The only slowdown came when the program was swapping between images every 16th frame. To get around this, my controller has the view quickly cycle through all the images beneath another view (like a curtain) so the user is only privy to a loading screen. Once the images have been cycled, the curtain view is removed and the animation (controlled by the user with a slider) moves like butter.
One way to do this would be to cut up the images with CGImageCreateWithImageInRect, like you started to above. Then, add them to an array:
myArray addObject:[UIImage imageWithCGImage:currentRef];
Next use a UIImageView with setAnimationImages, like this:
UIImageView *myAnimationImageView;
[myAnimationImageView setAnimationImages:myArray];
Then You can start the animation.
There is a good project doing this here: https://github.com/r3econ/UIImage-Sprite-Additions