I'm using SlideToCancel as per requirements to my project but i'm unable to find how to change the position of button.
I have gone through all the code but cannot figure.
Here is the main code:
import
#import "SlideToCancelViewController.h"
#interface SlideToCancelViewController()
- (void) setGradientLocations:(CGFloat)leftEdge;
- (void) startTimer;
- (void) stopTimer;
#end
static const CGFloat gradientWidth = 0.2;
static const CGFloat gradientDimAlpha = 0.5;
static const int animationFramesPerSec = 8;
#implementation SlideToCancelViewController
#synthesize delegate;
// Implement the "enabled" property
- (BOOL) enabled {
return slider.enabled;
}
- (void) setEnabled:(BOOL)enabled{
slider.enabled = enabled;
label.enabled = enabled;
if (enabled) {
slider.value = 0.0;
label.alpha = 1.0;
touchIsDown = NO;
[self startTimer];
} else {
[self stopTimer];
}
}
- (UILabel *)label {
// Access the view, which will force loadView to be called
// if it hasn't already been, which will create the label
(void)[self view];
return label;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
// Load the track background
UIImage *trackImage = [UIImage imageNamed:#"sliderTrack.png"];
sliderBackground = [[UIImageView alloc] initWithImage:trackImage];
// Create the superview same size as track backround, and add the background image to it
UIView *view = [[UIView alloc] initWithFrame:sliderBackground.frame];
[view addSubview:sliderBackground];
// Add the slider with correct geometry centered over the track
slider = [[UISlider alloc] initWithFrame:sliderBackground.frame];
CGRect sliderFrame = slider.frame;
sliderFrame.size.width -= 46; //each "edge" of the track is 23 pixels wide
slider.frame = sliderFrame;
slider.center = sliderBackground.center;
slider.backgroundColor = [UIColor clearColor];
[slider setMinimumTrackImage:[UIImage imageNamed:#"sliderMaxMin-02.png"] forState:UIControlStateNormal];
[slider setMaximumTrackImage:[UIImage imageNamed:#"sliderMaxMin-02.png"] forState:UIControlStateNormal];
UIImage *thumbImage = [UIImage imageNamed:#"sliderThumb.png"];
[slider setThumbImage:thumbImage forState:UIControlStateNormal];
slider.minimumValue = 0.0;
slider.maximumValue = 1.0;
slider.continuous = YES;
slider.value = 0.0;
// Set the slider action methods
[slider addTarget:self
action:#selector(sliderUp:)
forControlEvents:UIControlEventTouchUpInside];
[slider addTarget:self
action:#selector(sliderDown:)
forControlEvents:UIControlEventTouchDown];
[slider addTarget:self
action:#selector(sliderChanged:)
forControlEvents:UIControlEventValueChanged];
// Create the label with the actual size required by the text
// If you change the text, font, or font size by using the "label" property,
// you may need to recalculate the label's frame.
NSString *labelText = NSLocalizedString(#"slide to cancel", #"SlideToCancel label");
UIFont *labelFont = [UIFont systemFontOfSize:24];
CGSize labelSize = [labelText sizeWithFont:labelFont];
label = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, labelSize.width, labelSize.height)];
// Center the label over the slidable portion of the track
CGFloat labelHorizontalCenter = slider.center.x + (thumbImage.size.width / 2);
label.center = CGPointMake(labelHorizontalCenter, slider.center.y);
// Set other label attributes and add it to the view
label.textColor = [UIColor whiteColor];
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
label.font = labelFont;
label.text = labelText;
[view addSubview:label];
[view addSubview:slider];
// This property is set to NO (disabled) on creation.
// The caller must set it to YES to animate the slider.
// It should be set to NO (disabled) when the view is not visible, in order
// to turn off the timer and conserve CPU resources.
self.enabled = NO;
// Render the label text animation using our custom drawing code in
// the label's layer.
label.layer.delegate = self;
// Set the view controller's view property to all of the above
self.view = view;
// The view is retained by the superclass, so release our copy
[view release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
[self stopTimer];
[sliderBackground release], sliderBackground = nil;
[slider release], slider = nil;
[label release], label = nil;
}
// UISlider actions
- (void) sliderUp: (UISlider *) sender
{
//filter out duplicate sliderUp events
if (touchIsDown) {
touchIsDown = NO;
if (slider.value != 1.0) //if the value is not the max, slide this bad boy back to zero
{
[slider setValue: 0 animated: YES];
label.alpha = 1.0;
[self startTimer];
}
else {
//tell the delagate we are slid all the way to the right
[delegate cancelled];
}
}
}
- (void) sliderDown: (UISlider *) sender
{
touchIsDown = YES;
}
- (void) sliderChanged: (UISlider *) sender
{
// Fade the text as the slider moves to the right. This code makes the
// text totally dissapear when the slider is 35% of the way to the right.
label.alpha = MAX(0.0, 1.0 - (slider.value * 3.5));
// Stop the animation if the slider moved off the zero point
if (slider.value != 0) {
[self stopTimer];
[label.layer setNeedsDisplay];
}
}
// animationTimer methods
- (void)animationTimerFired:(NSTimer*)theTimer {
// Let the timer run for 2 * FPS rate before resetting.
// This gives one second of sliding the highlight off to the right, plus one
// additional second of uniform dimness
if (++animationTimerCount == (2 * animationFramesPerSec)) {
animationTimerCount = 0;
}
// Update the gradient for the next frame
[self setGradientLocations:((CGFloat)animationTimerCount/(CGFloat)animationFramesPerSec)];
}
- (void) startTimer {
if (!animationTimer) {
animationTimerCount = 0;
[self setGradientLocations:0];
animationTimer = [[NSTimer
scheduledTimerWithTimeInterval:1.0/animationFramesPerSec
target:self
selector:#selector(animationTimerFired:)
userInfo:nil
repeats:YES] retain];
}
}
- (void) stopTimer {
if (animationTimer) {
[animationTimer invalidate];
[animationTimer release], animationTimer = nil;
}
}
// label's layer delegate method
- (void)drawLayer:(CALayer *)theLayer
inContext:(CGContextRef)theContext
{
// Set the font
const char *labelFontName = [label.font.fontName UTF8String];
// Note: due to use of kCGEncodingMacRoman, this code only works with Roman alphabets!
// In order to support non-Roman alphabets, you need to add code generate glyphs,
// and use CGContextShowGlyphsAtPoint
CGContextSelectFont(theContext, labelFontName, label.font.pointSize, kCGEncodingMacRoman);
// Set Text Matrix
CGAffineTransform xform = CGAffineTransformMake(1.0, 0.0,
0.0, -1.0,
0.0, 0.0);
CGContextSetTextMatrix(theContext, xform);
// Set Drawing Mode to clipping path, to clip the gradient created below
CGContextSetTextDrawingMode (theContext, kCGTextClip);
// Draw the label's text
const char *text = [label.text cStringUsingEncoding:NSMacOSRomanStringEncoding];
CGContextShowTextAtPoint(
theContext,
0,
(size_t)label.font.ascender,
text,
strlen(text));
// Calculate text width
CGPoint textEnd = CGContextGetTextPosition(theContext);
// Get the foreground text color from the UILabel.
// Note: UIColor color space may be either monochrome or RGB.
// If monochrome, there are 2 components, including alpha.
// If RGB, there are 4 components, including alpha.
CGColorRef textColor = label.textColor.CGColor;
const CGFloat *components = CGColorGetComponents(textColor);
size_t numberOfComponents = CGColorGetNumberOfComponents(textColor);
BOOL isRGB = (numberOfComponents == 4);
CGFloat red = components[0];
CGFloat green = isRGB ? components[1] : components[0];
CGFloat blue = isRGB ? components[2] : components[0];
CGFloat alpha = isRGB ? components[3] : components[1];
// The gradient has 4 sections, whose relative positions are defined by
// the "gradientLocations" array:
// 1) from 0.0 to gradientLocations[0] (dim)
// 2) from gradientLocations[0] to gradientLocations[1] (increasing brightness)
// 3) from gradientLocations[1] to gradientLocations[2] (decreasing brightness)
// 4) from gradientLocations[3] to 1.0 (dim)
size_t num_locations = 3;
// The gradientComponents array is a 4 x 3 matrix. Each row of the matrix
// defines the R, G, B, and alpha values to be used by the corresponding
// element of the gradientLocations array
CGFloat gradientComponents[12];
for (int row = 0; row < num_locations; row++) {
int index = 4 * row;
gradientComponents[index++] = red;
gradientComponents[index++] = green;
gradientComponents[index++] = blue;
gradientComponents[index] = alpha * gradientDimAlpha;
}
// If animating, set the center of the gradient to be bright (maximum alpha)
// Otherwise it stays dim (as set above) leaving the text at uniform
// dim brightness
if (animationTimer) {
gradientComponents[7] = alpha;
}
// Load RGB Colorspace
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
// Create Gradient
CGGradientRef gradient = CGGradientCreateWithColorComponents (colorspace, gradientComponents,
gradientLocations, num_locations);
// Draw the gradient (using label text as the clipping path)
CGContextDrawLinearGradient (theContext, gradient, label.bounds.origin, textEnd, 0);
// Cleanup
CGGradientRelease(gradient);
CGColorSpaceRelease(colorspace);
}
- (void) setGradientLocations:(CGFloat) leftEdge {
// Subtract the gradient width to start the animation with the brightest
// part (center) of the gradient at left edge of the label text
leftEdge -= gradientWidth;
//position the bright segment of the gradient, keeping all segments within the range 0..1
gradientLocations[0] = leftEdge < 0.0 ? 0.0 : (leftEdge > 1.0 ? 1.0 : leftEdge);
gradientLocations[1] = MIN(leftEdge + gradientWidth, 1.0);
gradientLocations[2] = MIN(gradientLocations[1] + gradientWidth, 1.0);
// Re-render the label text
[label.layer setNeedsDisplay];
}
- (void)dealloc {
[self stopTimer];
[self viewDidUnload];
[super dealloc];
}
#end
Sorry for posting heavy code stuff.
P.S.: I know AppStore doesn't accepts this code but i'm interested to learn & do more on QuartzCore graphics than using interface builders.
Check this answer https://stackoverflow.com/a/25894355/1344237
You have to remove the label.layer.delegate = self;
Related
In this picture with a UITextView saying "Coordinate Geometry", the "e" gets put onto the next line. There is no line space there. I have also tried this with a UILabel (I switched to UITextView to try and fix the problem but there was no difference).
Here is my code for my subclass of UITextView
- (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text circular:(BOOL)isCircular {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor lightGrayColor];//[UIColor clearColor];
self.alpha = 0.5;
self.textColor = [Styles mainTextColour];
[self setFont:[Styles heading2Font]];
[self setTextAlignment:NSTextAlignmentCenter];
self.text = text;
self.editable = NO;
self.contentInset = UIEdgeInsetsMake(-8, 0, -8, 0);
[self resizeFontToFix];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
NSAssert(NO, #"Don't use BubbleText -initWithFrame:, use -initWithFrame: andText: instead");
return nil;
}
- (void)resizeFontToFix {
//Resize to fix
CGFloat fontSize = self.font.pointSize;
CGFloat minSize = 6.0 * [Styles sizeModifier];
while (fontSize > minSize && [self sizeThatFits:(CGSizeMake(self.frame.size.width, FLT_MAX))].height >= self.frame.size.height) {
fontSize -= 1.0;
self.font = [self.font fontWithSize:fontSize];
}
//this below resizes to fit and centres the resulting view
// [self resizeFrameAndCentre];
}
- (void)resizeFrameAndCentre {
CGRect originalFrame = self.frame;
[self sizeToFit];
CGPoint centre = self.center;
centre.x = originalFrame.origin.x + (originalFrame.size.width / 2);
centre.y = originalFrame.origin.y + (originalFrame.size.height / 2);
self.center = centre;
}
I am trying I make a UI label auto scroll the text that is inside it like a marquee. The below code works depending on what kind of text/content I throw at it. I can't tell what works and what does not. What happens is that the label does not show anything, then suddenly scrolls the text at an extremely high speed that you can't read it.
For some reason, this works perfectly on the iPhone but not on the iPad. I am guessing because the text I am putting at the iPhone is always way bigger than the Uilabel's size?
Here is the code:
self.currentTrack.textColor = [UIColor colorWithRed:15.0/255.0 green:176.0/255.0 blue:223.0/255.0 alpha:1];
self.currentTrack.labelSpacing = 35; // distance between start and end labels
self.currentTrack.pauseInterval = 1.7; // seconds of pause before scrolling starts again
self.currentTrack.scrollSpeed = 30; // pixels per second
self.currentTrack.textAlignment = NSTextAlignmentCenter; // centers text when no auto-scrolling is applied
self.currentTrack.fadeLength = 12.f;
self.currentTrack.scrollDirection = CBAutoScrollDirectionLeft;
[self.currentTrack observeApplicationNotifications];
}
Here is the code:
AutoScrollLabel, extended from UIView (code provided below) has an instance method to set text (setLabelText). The text provided will auto scroll only if the length of the text is bigger than the width of the AutoScrollLabel view.
Eg:
AutoScrollLabel *autoScrollLabel = [[AutoScrollLabel alloc] initWithFrame:CGRectMake(0, 0, 150, 25)];
[autoScrollLabel setLabelText:#"Some lengthy text to be scrolled"];
Note: You can make changes in setLabelText: Method implementation to support Attributed Text (use appropriate methods to find size of Attributed Text)
*** AutoScrollLabel.h
#interface AutoScrollLabel : UIView {
UILabel *textLabel;
NSTimer *timer;
}
- (void) setLabelText:(NSString*) text;
- (void) setLabelFont:(UIFont*)font;
- (void) setLabelTextColor:(UIColor*)color;
- (void) setLabelTextAlignment:(UITextAlignment)alignment;
#end
**** AutoScrollLabel.m
#import "AutoScrollLabel.h"
#import <QuartzCore/QuartzCore.h>
#implementation AutoScrollLabel
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.clipsToBounds = YES;
self.autoresizesSubviews = YES;
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
textLabel.backgroundColor = [UIColor clearColor];
textLabel.textColor = [UIColor blackColor];
textLabel.textAlignment = UITextAlignmentRight;
[self addSubview:textLabel];
}
return self;
}
-(void) setLabelText:(NSString*) text {
textLabel.text = text;
CGSize textSize = [text sizeWithFont:textLabel.font];
if(textSize.width > self.frame.size.width) {
textLabel.frame = CGRectMake(0, 0, textSize.width, self.frame.size.height);
}
else {
textLabel.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}
if(textLabel.frame.size.width > self.frame.size.width) {
[timer invalidate];
timer = nil;
CGRect frame = textLabel.frame;
frame.origin.x = self.frame.size.width-50;
textLabel.frame = frame;
timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(moveText) userInfo:nil repeats:YES];
}
else {
[timer invalidate];
timer = nil;
}
}
-(void) moveText {
if(textLabel.frame.origin.x < textLabel.frame.size.width-2*textLabel.frame.size.width) {
CGRect frame = textLabel.frame;
frame.origin.x = self.frame.size.width;
textLabel.frame = frame;
}
[UIView beginAnimations:nil context:nil];
CGRect frame = textLabel.frame;
frame.origin.x -= 5;
textLabel.frame = frame;
[UIView commitAnimations];
}
- (void) setLabelFont:(UIFont*)font {
textLabel.font = font;
}
- (void) setLabelTextColor:(UIColor*)color {
textLabel.textColor = color;
}
- (void) setLabelTextAlignment:(UITextAlignment)alignment {
textLabel.textAlignment = alignment;
}
For Swift5
set top of your UILabel equal to superview bottom, and then use this code:
func createAnimationLbl() -> CAAnimation {
let animation = CABasicAnimation(keyPath: "transform.translation.y")
animation.fromValue = 0
animation.toValue = -(self.view.frame.height )
animation.duration = 15
animation.repeatCount = Float.infinity //times of scrolling, infinity for unlimited times.
animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.linear)
animation.fillMode = CAMediaTimingFillMode.forwards
animation.isRemovedOnCompletion = false
return animation
}
then in your viewWillAppear call it as below:
self.aboutLbl.layer.add(createAnimationLbl(), forKey: nil)
I've created this custom UIView named RoundView:
#import <QuartzCore/QuartzCore.h>
#implementation RoundedView
+(UIColor *)grayUIColor {
return [UIColor colorWithRed:161.0/255.0 green:157.0/255.0 blue:164.0/255.0 alpha:1.0];
}
+(UIColor *)darkBlueUIColor {
return [UIColor colorWithRed:86.0/255.0 green:88.0/255.0 blue:87.0/255.0 alpha:1];
}
+(UIColor *)greenUIColor {
return [UIColor colorWithRed:51.0/255.0 green:141.0/255.0 blue:130.0/255.0 alpha:1];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self)
{
//add pico icon as default image
_defaultImage = [UIImage imageNamed:#"actionBar_pico_icon"];
_isCreated = NO;
}
return self;
}
-(UIView*)createRoundViewWithBorder:(UIColor*)borderColor andPaddingColor:(UIColor*)paddingColor{
_borderColor = borderColor;
_paddingBackgroundColor = paddingColor;
[self setViewAppearance];
[self addImageToView];
_isCreated = YES;
return self;
}
/**
Set the current view appearance
*/
-(void) setViewAppearance {
self.layer.borderWidth = 1.5;
self.layer.borderColor = [_borderColor CGColor];
self.backgroundColor = _paddingBackgroundColor;
}
-(void) addImageToView {
CGRect frame = CGRectMake(0, 0, self.frame.size.width - 5, self.frame.size.height - 5);
_imageView = [[UIImageView alloc] initWithFrame:frame];
//calculate center x
float x = (self.frame.size.width - _imageView.frame.size.width) / 2;
//calculate center y
float y = (self.frame.size.height - _imageView.frame.size.height) / 2;
//create new frame
frame = CGRectMake(x, y, _imageView.frame.size.width, _imageView.frame.size.height);
_imageView.image = _defaultImage;
_imageView.frame = frame;
_imageView.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:_imageView];
[self makeViewRounded:_imageView];
[self makeViewRounded:self];
}
-(UIView*) makeViewRounded:(UIView*)view {
//set the look of the image
view.layer.cornerRadius= self.frame.size.height /2;
view.layer.opaque = NO;
view.layer.masksToBounds = YES;
return view;
}
-(void)updateImage:(UIImage *)image {
_image = image;
_imageView.image = image;
}
-(void)reset {
[self updateImage:_defaultImage];
}
#end
an example for the output will be :
If you look closely you will notice that the border is a circle, but the image view has edges.
How can i make the Image smooth as well ?
self.imgViewbg.layer.cornerRadius = self.imgViewbg.frame.size.width / 2;
self.imgViewbg.clipsToBounds = YES;
u Can Try This Code. And Implement in your Project..
It Will Definetly Work.. for u
I think the problem seems to be here:
view.layer.cornerRadius= self.frame.size.height /2;
Try giving it a constant small number and see the change. May be the height/2 is not making a perfect circle. You can give a smaller value than height/2 and see the change. It a wild guess by watching your image.
In one of my views I have a bottom bar. A tap on this view animates a temporary cart half way to the screen. Now, where there is no item in the temporary table I show a no data overlay which is nothing but a view with an empty cart image and text underneath it.
The issue is: when this table animates to expand and collapse, the no data overlay does not look good during animation. It appears that the image is also shrinking/expanding until the temporary table view stops animating.
So, I tried by playing with the alpha of the temporary table view while this animation happens so that it does not look that bad. But this is not helping either. There is an abrupt flash in the end.
Any suggestions?
self.temporaryTable.backgroundView = self.noDataOverlay;
[UIView animateWithDuration:0.5 animations:^{
self.temporaryTable.alpha = 0.5;
} completion:^(BOOL finished) {
self.temporaryTable.alpha = 1.0;
}];
Here is my code for drawing the image:
- (void)drawRect:(CGRect)iRect scalingImage:(BOOL)iShouldScale {
CGRect aRect = self.superview.bounds;
// Draw our image
CGRect anImageRect = iRect;
if (self.image) {
//scale the image based on the height
anImageRect = CGRectZero;
anImageRect.size.height = self.image.size.height;
anImageRect.size.width = self.image.size.width;
#ifdef ACINTERNAL
if (iShouldScale) {
anImageRect = [self aspectFittedRect:anImageRect max:aRect];
} else {
anImageRect.origin.x = (iRect.size.width/2) - (anImageRect.size.width/2);
anImageRect.origin.y = kTopMargin;
}
#else
anImageRect.origin.x = (iRect.size.width/2) - (anImageRect.size.width/2);
anImageRect.origin.y = kTopMargin;
#endif
if (self.shouldCenterImage)
anImageRect.origin.y = (iRect.size.height/2) - (anImageRect.size.height/2);
[self.image drawInRect:anImageRect];
} else {
anImageRect.origin.y = (iRect.size.height/6);
anImageRect.size.height = (iRect.size.height/6);
}
// Draw our title and message
if (self.title) {
CGFloat aTop = anImageRect.origin.y + anImageRect.size.height + kSpacer;
CGFloat aWidth = aRect.size.width;
UIColor *aColor = [UIColor colorWithRed:96/256.0 green:106/256.0 blue:122/256.0 alpha:1];
[aColor set];
CGRect aTextRect = CGRectMake(0, aTop, aWidth, kTitleHeight * 2);
UIFont *aTitleFont = [UIFont boldSystemFontOfSize:kTitleFontSize];
[self.title drawInRect:aTextRect withFont:aTitleFont lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
if (self.subTitle) {
UIFont *aSubTitleFont = [UIFont systemFontOfSize:kSubTitleFontSize];
aTextRect = CGRectMake(0, aTop+kSpacer, aWidth, kTitleHeight);
[self.subTitle drawInRect:aTextRect withFont:aSubTitleFont lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
}
}
}
- (void)addToView:(UIView *)iView {
// setting a unique tag number here so that if the user has any other tag there should not be a conflict
UIView *aView = [iView viewWithTag:699];
if (aView) {
[aView removeFromSuperview];
}
self.tag = 699;
[iView addSubview:self];
}
- (void)removeView {
[super removeFromSuperview];
}
-(void)setViewFrame:(CGRect) iFrame {
CGRect aRect = self.frame;
aRect.size.width = iFrame.size.width;
aRect.size.height = iFrame.size.height;
self.frame = aRect;
[self setNeedsDisplay];
}
- (CGRect)aspectFittedRect:(CGRect)iRect max:(CGRect)iMaxRect {
float anOriginalAspectRatio = iRect.size.width / iRect.size.height;
float aMaxAspectRatio = iMaxRect.size.width / iMaxRect.size.height;
CGRect aNewRect = iMaxRect;
if (anOriginalAspectRatio > aMaxAspectRatio) { // scale by width
aNewRect.size.height = iMaxRect.size.width * iRect.size.height / iRect.size.width;
} else {
aNewRect.size.width = iMaxRect.size.height * iRect.size.width / iRect.size.height;
}
aNewRect.origin.y = (iMaxRect.size.height - aNewRect.size.height)/2.0;
aNewRect.origin.x = (iMaxRect.size.width - aNewRect.size.width)/2.0;
return CGRectIntegral(aNewRect);
}
One possibility here is to fix the original problem, namely the fact that the empty cart image is expanding/collapsing as the view animates. Without seeing your code it is difficult to solve this problem, but in my own code what I do is set the contentMode of the UIImageView to UIViewContentModeBottom. This causes the image to stay the same size even though the image view that contains it may grow and shrink as part of the animation.
You see a flash because you animate alpha up to 0.5 and then when animation completes you set it from 0.5 to 1.0. Just animate the alpha up to 1.0:
[UIView animateWithDuration:0.5
animations:^
{
self.temporaryTable.alpha = 1.0;
}];
I have a text in a "bubble" by fitting the text inside an image as shown below. it works fine except the text is not copyable. I need to have "copy" option so that when user tab on the text (or bubble image") "cop" options is displayed, just like in when user tab into the built in SMS Message bubble.
#import "SpeechBubbleView.h"
static UIFont* font = nil;
static UIImage* lefthandImage = nil;
static UIImage* righthandImage = nil;
const CGFloat VertPadding = 4; // additional padding around the edges
const CGFloat HorzPadding = 4;
const CGFloat TextLeftMargin = 17; // insets for the text
const CGFloat TextRightMargin = 15;
const CGFloat TextTopMargin = 10;
const CGFloat TextBottomMargin = 11;
const CGFloat MinBubbleWidth = 50; // minimum width of the bubble
const CGFloat MinBubbleHeight = 40; // minimum height of the bubble
const CGFloat WrapWidth = 200; // maximum width of text in the bubble
#implementation SpeechBubbleView
+ (void)initialize
{
if (self == [SpeechBubbleView class])
{
font = /*[*/ [UIFont systemFontOfSize:[UIFont systemFontSize]] /*retain]*/;
lefthandImage = /*[*/ [[UIImage imageNamed:/*#"BubbleLefthand"*/#"lefttest4"]
stretchableImageWithLeftCapWidth:20 topCapHeight:19] /*retain]*/;
righthandImage = /*[*/[[UIImage imageNamed:/*#"BubbleRighthand"*/#"righttest4"]
stretchableImageWithLeftCapWidth:20 topCapHeight:19] /*retain]*/;
}
}
+ (CGSize)sizeForText:(NSString*)text
{
CGSize textSize = [text sizeWithFont:font
constrainedToSize:CGSizeMake(WrapWidth, 9999)
lineBreakMode:UILineBreakModeWordWrap];
CGSize bubbleSize;
bubbleSize.width = textSize.width + TextLeftMargin + TextRightMargin;
bubbleSize.height = textSize.height + TextTopMargin + TextBottomMargin;
if (bubbleSize.width < MinBubbleWidth)
bubbleSize.width = MinBubbleWidth;
if (bubbleSize.height < MinBubbleHeight)
bubbleSize.height = MinBubbleHeight;
bubbleSize.width += HorzPadding*2;
bubbleSize.height += VertPadding*2;
return bubbleSize;
}
- (void)drawRect:(CGRect)rect
{
[self.backgroundColor setFill];
UIRectFill(rect);
CGRect bubbleRect = CGRectInset(self.bounds, VertPadding, HorzPadding);
CGRect textRect;
textRect.origin.y = bubbleRect.origin.y + TextTopMargin;
textRect.size.width = bubbleRect.size.width - TextLeftMargin - TextRightMargin;
textRect.size.height = bubbleRect.size.height - TextTopMargin - TextBottomMargin;
if (bubbleType == BubbleTypeLefthand)
{
[lefthandImage drawInRect:bubbleRect];
textRect.origin.x = bubbleRect.origin.x + TextLeftMargin;
}
else
{
[righthandImage drawInRect:bubbleRect];
textRect.origin.x = bubbleRect.origin.x + TextRightMargin;
}
[[UIColor blackColor] set];
[text drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeWordWrap];
}
- (void)setText:(NSString*)newText bubbleType:(BubbleType)newBubbleType
{
//[text release];
/**
handle local
**/
// text = [newText copy];
text = [newText copy];
bubbleType = newBubbleType;
[self setNeedsDisplay];
}
- (void)dealloc
{
//[text release];
//[super dealloc];
}
#end
If you want the system cut/copy/paste menu (or some subset thereof) without the full suite of text editability features from UITextField or UITextView, you need to present your own UIMenuController. Doing this requires:
the control to be affected by the menu can become first responder
said control (or something sensible in the responder chain above it) implements the editing methods (e.g. copy:) you want to support
you perform some event handling to present the menu controller at an appropriate time (e.g. a gesture recognizer action)
As is often the case, there's a good tutorial on NSHipster with both Swift and ObjC sample code. Kudos to #mattt, though I'd say this line needs a correction:
If you’re wondering why, oh why, this isn’t just built into UILabel, well… join the club.
"Join the club" should be replaced with "file a bug". It even sorta almost rhymes!