Cropping UIView - ios

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;

Related

The height of the weex <text> component is not accurate?

The current WeexSDK version 0.18.0,I use show similar effect on the simulator and the real machine and the text can't be fully displayed as shown below.
Also I've added the script to show how to calculate the height of the text component in source code is done. suggestSize.heightis always the height I want, but this code is only executed under iOS10. The value of totalHeight is always worse when I have more text lines than iOS10. How do I solve this?
The effect is as follows:
The source code:
- (CGSize)calculateTextHeightWithWidth:(CGFloat)aWidth
{
CGFloat totalHeight = 0;
CGSize suggestSize = CGSizeZero;
NSAttributedString * attributedStringCpy = [self ctAttributedString];
if (!attributedStringCpy) {
return CGSizeZero;
}
if (isnan(aWidth)) {
aWidth = CGFLOAT_MAX;
}
aWidth = [attributedStringCpy boundingRectWithSize:CGSizeMake(aWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil].size.width;
/* Must get ceil of aWidth. Or core text may not return correct bounds.
Maybe aWidth without ceiling triggered some critical conditions. */
aWidth = ceil(aWidth);
CTFramesetterRef ctframesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attributedStringCpy));
suggestSize = CTFramesetterSuggestFrameSizeWithConstraints(ctframesetterRef, CFRangeMake(0, 0), NULL, CGSizeMake(aWidth, MAXFLOAT), NULL);
if (_lines == 0) {
// If not line limit use suggestSize directly.
CFRelease(ctframesetterRef);
return CGSizeMake(aWidth, suggestSize.height);
}
CGMutablePathRef path = NULL;
path = CGPathCreateMutable();
// sufficient height to draw text
CGPathAddRect(path, NULL, CGRectMake(0, 0, aWidth, suggestSize.height * 10));
CTFrameRef frameRef = NULL;
frameRef = CTFramesetterCreateFrame(ctframesetterRef, CFRangeMake(0, attributedStringCpy.length), path, NULL);
CGPathRelease(path);
CFRelease(ctframesetterRef);
if (NULL == frameRef) {
//try to protect unexpected crash.
return suggestSize;
}
CFArrayRef lines = CTFrameGetLines(frameRef);
CFIndex lineCount = CFArrayGetCount(lines);
CGFloat ascent = 0;
CGFloat descent = 0;
CGFloat leading = 0;
// height = ascent + descent + lineCount*leading
// ignore linespaing
NSUInteger actualLineCount = 0;
for (CFIndex lineIndex = 0; (!_lines|| lineIndex < _lines) && lineIndex < lineCount; lineIndex ++)
{
CTLineRef lineRef = NULL;
lineRef = (CTLineRef)CFArrayGetValueAtIndex(lines, lineIndex);
CTLineGetTypographicBounds(lineRef, &ascent, &descent, &leading);
totalHeight += ascent + descent;
actualLineCount ++;
}
totalHeight = totalHeight + actualLineCount * leading;
CFRelease(frameRef);
if (WX_SYS_VERSION_LESS_THAN(#"10.0")) {
// there is something wrong with coreText drawing text height, trying to fix this with more efficent way.
if(actualLineCount && actualLineCount < lineCount) {
suggestSize.height = suggestSize.height * actualLineCount / lineCount;
}
return CGSizeMake(aWidth, suggestSize.height);
}
return CGSizeMake(aWidth, totalHeight);
}

Unable to scale shapes to match the dimensions of UIView

I have created a custom view that draws shapes of varying sides. The view is added to main view as a subview as given below. The shapes are of different dimensions.
My source code is given below
-(instancetype) initWithSides:(NSUInteger) sides andFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setBackgroundColor:[UIColor clearColor]];
self.sides = sides;
self.radius = CGRectGetWidth(self.frame) * 1.5 / sides);
}
return self;
}
-(void) drawRect:(CGRect) frame {
// Sides is passed as constructor argument. 4 sides means a quadrilateral etc.
// Get CGPAthRef instance
CGFloat angle = DEGREES_TO_RADIANS(360 / ((CGFloat) self.sides));
int count = 0;
CGFloat xCoord = CGRectGetMidX(self.frame);
CGFloat yCoord = CGRectGetMidY(self.frame);
while (count < self.sides) {
CGFloat xPosition =
xCoord + self.radius * cos(angle * ((CGFloat) count));
CGFloat yPosition =
yCoord + self.radius * sin(angle * ((CGFloat) count));
[self.points addObject:[NSValue valueWithCGPoint:CGPointMake(xPosition, yPosition)]];
count ++;
}
NSValue* v = [self.points firstObject];
CGPoint first = v.CGPointValue;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, first.x, first.y);
for (int ix = 1; ix < [self.points count]; ix++) {
NSValue* pValue = [self.points objectAtIndex:ix];
CGPoint p = pValue.CGPointValue;
CGPathAddLineToPoint(path, nil, p.x, p.y);
}
CGPathCloseSubpath(path);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddPath(context, path);
[self colourView:context withPath:path];
}
-(void) colourView:(CGContextRef) context withPath:(CGPathRef) ref {
NSUInteger num = arc4random_uniform(8) + 1;
UIColor* color = nil;
switch (num) {
case 1:
color = [UIColor redColor];
break;
case 2:
color = [UIColor greenColor];
break;
case 3:
color = [UIColor yellowColor];
break;
case 4:
color = [UIColor blueColor];
break;
case 5:
color = [UIColor orangeColor];
break;
case 6:
color = [UIColor brownColor];
break;
case 7:
color = [UIColor purpleColor];
break;
case 8:
color = [UIColor blackColor];
break;
default:
break;
}
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillPath(context);
}
This constitutes one single shape. This is how I am drawing the rest of the views.
-(void) initDrawView {
NSUInteger width = CGRectGetWidth(self.view.bounds) / 8;
NSUInteger height = (CGRectGetHeight(self.view.frame))/ 8;
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
for (int i = 0 ; i < 8; i++) {
CGFloat yCoord = i * height + i * 15;
for (int j = 0; j < 8; j ++) {
int side = 3 + arc4random() % 8;
CGFloat xCoord = j * width;
SimpleRegularPolygonView* view =
[[SimpleRegularPolygonView alloc] initWithSides:side andFrame:CGRectMake(xCoord, yCoord, width, height)];
[view sizeToFit];
view.viewEffectsDelegate = self;
[view setTag: (8 * i + j)];
[self.view addGestureRecognizer:singleFingerTap];
[self.view addSubview:view];
}
}
}
1) I don't know how to make them have the same dimensions. How can I do that? (First image)
2) the images don't scale up to the size of the UIView (Second image).
Your current code makes the radius inversely proportional to the number of sides:
self.radius = CGRectGetWidth(self.frame) * 1.5 / sides;
so the more sides, the smaller the image. A quick fix would be to just make the radius half the frame width:
self.radius = CGRectGetWidth(self.frame) /2;
This will mean shapes with an even number of sides fill the frame width. But those with an odd number of sides will appear to have space to the left. If you want to adjust for that you will need more detailed calculations for the width, and you will also need to move the "centre" of the shape. For an odd number sides, the radius would need to be:
self.radius = CGRectGetWidth(self.frame) /(1 + cos(angle / 2));
and xCoord would need to be:
CGFloat xCoord = CGRectGetMinX(self.frame) + self.radius * cos(angle/2);

Implementing Grid/table drawing algorithm

I'm trying to implement universal method for generating (drawing) grid formed with UIViews (or other controls). They all should have borders and my problem is I cannot find right algorithm to shift (combine) borders (so the "table" does not have double cell borders like now) and to increase size so the views exactly match given frame (red on picture).
Following code generates picture beneath:
////////
const CGFloat kOuterBorderWidth = 0.0;
const CGFloat kInnerBorderWidth = 1.0;
NSArray *rows;
NSArray *columns = rows = #[#0.065, #0.29, #0.29, #0.29, #0.065];
NSMutableArray *cells = [self drawGridWithFrame:self.frame
columns:columns
rows:rows
outerBorderWidth:kOuterBorderWidth
innerBordersWidth:kInnerBorderWidth];
///////
and the method itself
- (NSMutableArray*)drawGridWithFrame:(CGRect)frame
columns:(NSArray *)columns
rows:(NSArray *)rows
outerBorderWidth:(CGFloat)outerBorderWidth
innerBordersWidth:(CGFloat)innerBordersWidth
{
CGFloat x = 0, y = 0;
NSMutableArray *cells = [NSMutableArray new];
CGFloat height = [rows[0] floatValue] * frame.size.height;
for (int j = 0; j < columns.count; j++) {
CGFloat width = [columns[j] floatValue] * frame.size.width;
CGRect cellFrame = CGRectMake(x, y, width, height);
UIView *cellView = [[UIView alloc] initWithFrame:cellFrame];
cellView.layer.borderWidth = innerBordersWidth;
if (j == 0 || j == columns.count - 1) {
cellView.layer.borderColor = [UIColor magentaColor].CGColor;
}
if (j == 1) {
cellView.layer.borderColor = [UIColor orangeColor].CGColor;
}
if (j == 2) {
cellView.layer.borderColor = [UIColor brownColor].CGColor;
}
[cells addObject:cellView];
x += [columns[j] floatValue] * frame.size.width;
}
return cells;
}
Done it.
Note: outerBorderWidth is now not used here, if it is > 1.0pt, then we additionally should shift views and adjust their size
- (NSMutableArray*)drawGridWithFrame:(CGRect)frame
columns:(NSArray *)columns
rows:(NSArray *)rows
outerBorderWidth:(CGFloat)outerBorderWidth
innerBordersWidth:(CGFloat)innerBordersWidth
{
CGFloat x = 0, y = 0;
NSMutableArray *cells = [NSMutableArray new];
CGFloat heightAdjust = (CGFloat)(rows.count - 1) / (CGFloat)rows.count;
CGFloat widthAdjust = (CGFloat)(columns.count - 1) / (CGFloat)columns.count;
for (int i = 0; i < rows.count; i++) {
CGFloat height = [rows[i] floatValue] * frame.size.height + innerBordersWidth * heightAdjust;
for (int j = 0; j < columns.count; j++) {
CGFloat width = [columns[j] floatValue] * frame.size.width + innerBordersWidth * widthAdjust;
CGRect cellFrame = CGRectMake(x, y, width, height);
UIView *cellView = [[UIView alloc] initWithFrame:cellFrame];
cellView.layer.borderWidth = innerBordersWidth;
if (j == 0 || j == columns.count - 1) {
cellView.layer.borderColor = [UIColor magentaColor].CGColor;
}
if (j == 1) {
cellView.layer.borderColor = [UIColor orangeColor].CGColor;
}
if (j == 2) {
cellView.layer.borderColor = [UIColor brownColor].CGColor;
}
[cells addObject:cellView];
x += width - innerBordersWidth;
}
x = 0;
y += height - innerBordersWidth;
}
return cells;
}
Result:

Star-Half image is not displaying in Custom RatingView IOS

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;

AMSlideMenu UI mess up when receives a call (In-Call Status bar)

Library : https://github.com/SocialObjects-Software/AMSlideMenu
Problem : When you are in closed menu state and receives a call(Simply simulate in iOS simulator) after ending call or while in the call if you try to open slide menu, Menu will appear as little bit smaller.
Any better workarounds for this?
Quick workaround,
Go to AMSlideMenuMainViewController.m
Replace below methods in the file,
- (void)openRightMenu
{
CGRect frame = self.rightMenu.view.frame;
frame.origin.x = [UIScreen mainScreen].bounds.size.width - [self rightMenuWidth];
frame.origin.y = 0;
frame.size = [UIScreen mainScreen].bounds.size;
frame.size.width = [self rightMenuWidth];
self.rightMenu.view.frame = frame;
[self openRightMenuAnimated:YES];
}
- (void)openLeftMenu
{
CGRect frame = self.leftMenu.view.frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size = [UIScreen mainScreen].bounds.size;
self.leftMenu.view.frame = frame;
[self openLeftMenuAnimated:YES];
}
And this,
- (void)configure3DTransformForMenu:(AMSlideMenu)menu panningView:(UIView *)panningView
{
float cx = 0;
float cy = 0;
float cz = 0;
float opacity = 0;
/********************************************* DEEPNESS EFFECT *******************************************************/
if (menu == AMSlideMenuLeft && panningView.frame.origin.x != 0 && [self deepnessForLeftMenu])
{
//Workaround for in-call status bar
CGRect frame = self.leftMenu.view.frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size = [UIScreen mainScreen].bounds.size;
self.leftMenu.view.frame = frame;
//end workaround for in-call status bar
cx = kMenuTransformScale.m11 + (panningView.frame.origin.x / [self leftMenuWidth]) * (1.0 - kMenuTransformScale.m11);
cy = kMenuTransformScale.m22 + (panningView.frame.origin.x / [self leftMenuWidth]) * (1.0 - kMenuTransformScale.m22);
cz = kMenuTransformScale.m33 + (panningView.frame.origin.x / [self leftMenuWidth]) * (1.0 - kMenuTransformScale.m33);
opacity = kMenuLayerInitialOpacity + (panningView.frame.origin.x / [self leftMenuWidth]) * (1.0 - kMenuLayerInitialOpacity);
self.leftMenu.view.layer.transform = CATransform3DMakeScale(cx, cy, cz);
self.leftMenu.view.layer.opacity = opacity;
}
else if (menu == AMSlideMenuRight && panningView.frame.origin.x != 0 && [self deepnessForRightMenu])
{
//Workaround for in-call status bar
CGRect frame = self.rightMenu.view.frame;
frame.origin.x = [UIScreen mainScreen].bounds.size.width - [self rightMenuWidth];
frame.origin.y = 0;
frame.size = [UIScreen mainScreen].bounds.size;
frame.size.width = [self rightMenuWidth];
self.rightMenu.view.frame = frame;
//end workaround for in-call status bar
cx = kMenuTransformScale.m11 + (-panningView.frame.origin.x / [self rightMenuWidth]) * (1.0 - kMenuTransformScale.m11);
cy = kMenuTransformScale.m22 + (-panningView.frame.origin.x / [self rightMenuWidth]) * (1.0 - kMenuTransformScale.m22);
cz = kMenuTransformScale.m33 + (-panningView.frame.origin.x / [self rightMenuWidth]) * (1.0 - kMenuTransformScale.m33);
opacity = kMenuLayerInitialOpacity + (-panningView.frame.origin.x / [self rightMenuWidth]) * (1.0 - kMenuLayerInitialOpacity);
self.rightMenu.view.layer.transform = CATransform3DMakeScale(cx, cy, cz);
self.rightMenu.view.layer.opacity = opacity;
}
/********************************************* DEEPNESS EFFECT *******************************************************/
/********************************************* STATUS BAR FIX *******************************************************/
if (menu == AMSlideMenuLeft && panningView.frame.origin.x != 0)
{
if (self.statusBarView)
{
self.statusBarView.layer.opacity = 1 - panningView.frame.origin.x / [self leftMenuWidth];
}
}
else if (menu == AMSlideMenuRight && panningView.frame.origin.x != 0)
{
if (self.statusBarView)
{
self.statusBarView.layer.opacity = 1 - abs(panningView.frame.origin.x) / [self rightMenuWidth];
}
}
/********************************************* STATUS BAR FIX *******************************************************/
/********************************************* DARKNESS EFFECT *******************************************************/
if (menu == AMSlideMenuLeft)
{
CGFloat alpha = [self maxDarknessWhileLeftMenu] * (panningView.frame.origin.x / [self leftMenuWidth]);
self.darknessView.alpha = alpha;
}
else if(menu == AMSlideMenuRight)
{
CGFloat alpha = [self maxDarknessWhileRightMenu] * (abs(panningView.frame.origin.x) / [self rightMenuWidth]);
self.darknessView.alpha = alpha;
}
/********************************************* DARKNESS EFFECT *******************************************************/
}

Resources