MonoTouch: How to change control's location at runtime? - uiview

I want to change the location of an UIImageView at runtime. In IB, I can change X coordinate to relocate it. So, I tried this code:
imageView.Frame.X = 25;
But it doesn't have any effect. Why? I have the same problem for other controls as well. How to make it work?

The Frame property is a value type, this means that if you do:
imageView.Frame.X = 25
what you are actually doing is:
var temp = imageView.Frame;
temp.X = 25;
The value never reaches the imageView. With value types, you have to assign a fully constructed type, so for example:
var current = imageView.Frame;
current.X = 25;
imageView.Frame = current;

The Frame property is a value type, this means that if you do:
imageView.Frame.X = 25
what you are actually doing is:
var temp = imageView.Frame;
temp.X = 25;
The value never reaches the imageView. With value types, you have to assign a fully constructed type, so for example:
var current = imageView.Frame;
current.X = 25;
imageView.Frame = current;

// The Code is quite simple and self explanatory
dispatch_async(dispatch_get_main_queue(), ^{
self.myimageView.frame = CGRectMake(140, 70, 140, 128);
});
By using >dispatch_async(dispatch_get_main_queue(), ^{ I made the code to run in the main queue, not in the background.

Related

Read CGFloat from Anchor Constraints

I created an UIView and then added the Anchor constraints but I have a problem when I want to read the values ...
In this case as you see, I created an NSLayoutConstraint property to get the Anchor Width of my uiview ... I then created a CGFloat that contains constraint but my NSLog always returns me a ZERO value.
where am I wrong? how can I get the width values of my UIView assigned to the Anchors?
UIView *trackLine = [[UIView alloc] init];
trackLine.backgroundColor = [self trackLineColor];
trackLine.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:trackLine];
[trackLine.topAnchor constraintEqualToAnchor:mediaTitle.bottomAnchor constant:25].active = YES;
[trackLine.rightAnchor constraintEqualToAnchor:self.rightAnchor].active = YES;
[trackLine.heightAnchor constraintEqualToConstant:1].active = YES;
self.width = [trackLine.widthAnchor constraintEqualToAnchor:self.widthAnchor multiplier:.8];
self.width.active = YES;
CGFloat trackLineLenght = self.width.constant;
NSLog(#"TRACK LINE %f", trackLineLenght );
NSLog Result:
**2017-10-21 17:10:35.096562+0200 [5501:1994879] TRACK LINE 0.000000**
OK - a little confusion...
First, don't use "width" as a property name... very confusing, since width is used in so many places already.
So, let's assume you have:
#property NSLayoutConstraint *trackLineWidthConstraint;
A .widthAnchor doesn't really have a width in terms of "what's the width of the anchor." The way you are defining your constraints:
self.trackLineWidthConstraint = [trackLine.widthAnchor constraintEqualToAnchor:self.widthAnchor multiplier:.8];
Says "set the .trackLineWidthConstraint property to 80% of the width of self. So, whenever the actual width of self changes, the actual width of your trackLine view will change to 80% of the new width.
The .constant is Zero. If it was something other than zero, that value would be added after calculating 80%. For example:
self.trackLineWidthConstraint = [trackLine.widthAnchor constraintEqualToAnchor:self.widthAnchor multiplier:.8];
// if self is 200-pts wide, trackLine will be 160-pts
self.trackLineWidthConstraint.constant = 10
// trackLine width is now (200 * 0.8) + 10, or 170-pts
If you want to get the current width of trackLine, you can get it from its .frame (after auto-layout has finished).
Hopefully, that didn't just make it more confusing :)

How To Use CCSlider in Cocos2d v3.2.1?

I am new in cocos2d iPhone development.My question is how to use CCSlider in Cocos2d v3.2.
CCSlider has only two parameter (background spriteFrame and HandleImage).How we can change the colour/Image of slider when we change the Thumb position.How we can differentiate between empty and full bars, how to make progress of filling?
Suppose I want to use to colour like red(Empty) and green(Fill)/two different images for slider.By default the slider colour is red means the slider value is 0.0f(Empty).if I increase the value of slider then the slider colour will change to green(Fill) from position 0.0 to current thumb position.Please help me.sorry for my question i am very week in english
Thank You.
Here is how i use CCSlider for volume control. This code is in the init method of a GameOptions menu class:
CCSpriteFrame *frRuler = [CCSpriteFrame frameWithImageNamed:#"slider_track.png"];
CCSpriteFrame *frKnob = [CCSpriteFrame frameWithImageNamed:#"slider_knob.png"];
_mainGain = [[CCSlider alloc] initWithBackground:frRuler andHandleImage:frKnob];
[self addChild:_mainGain];
[_mainGain setTarget:self selector:#selector(onMainGainChange:)];
_mainGain.anchorPoint = ccp(.5, .5);
_mainGain.visible = YES;
_mainGain.positionType = CCPositionTypePoints;
_mainGain.position = ccp(kScreenWidth / 2, kScreenHeight / 2 - 55);
_mainGain.continuous = YES;
_mainGain.sliderValue = _battlesSettings.audio.masterVolumeGain; // initial
with the following method to receive the slider control 'slide' events :
- (void)onMainGainChange:(id)sender {
CCSlider *sl = (CCSlider *) sender;
_battlesSettings.audio.masterVolumeGain = sl.sliderValue;
_isSettingsDirty = YES;
}

Two Views, one appears sometimes and when so, the other one takes it space

I have an image and a label who are are next to each other inside a TableCell (among other elements). Sometimes the image has to be shown, and sometimes not.
What I want is that the label takes all space when the image has to be hidden, and respects its space (so it does not appear over the image) when it has to be shown.
In Android I would not have a problem doing it; I would put those two elements in a LinearLayout and I would mark the imageĀ“s visibility as GONE when I have to hide it, and then the text would start naturally where the image should be. But with the storyboard I am a bit lost and I do not know how to control this wanted behaviour. Is there a similar technique as the one that I mentioned for Android? I have to achieve it without AutoLayout.
I tried to change the origin of the frame of the label when the image is there, but it got all weird when the table downloads new elements:
- (void)displayImage
{
self.image.hidden = !_question.showImage;
// Make a bit extra space for the image
if(_question.showImage){
CGRect labelFrame = [self.unreadLabel frame];
labelFrame.origin.x = labelFrame.origin.x +20;
[self.unreadLabel setFrame:labelFrame];
}
}
Ok, I was not taking into account that the cells are recycled and that I had to set them up also when the text has to take all space.
The resulting method would look like this:
- (void)displayImage
{
self.image.hidden = !_question.image;
// Make a bit extra space for the image
CGRect labelFrame = [self.unreadLabel frame];
CGRect imageFrame = [self.image frame];
if(_question.showimage){
labelFrame.origin.x = imageFrame.origin.x + imageFrame.size.width + 3;
[self.unreadLabel setFrame:labelFrame];
} else{
labelFrame.origin.x = imageFrame.origin.x ;
[self.unreadLabel setFrame:labelFrame];
}
}

weakSelf when setting frame

I recently read this post and figured it would be a good idea to use the tips from the article. I'm using it in blocks, but should I also use it in the 'block' below. Is the 'block' below a real block?
avatar.frame = ({
CGRect frame = avatar.frame;
frame.origin.y = CGRectGetMaxY(self.view);
frame;
});
That would become:
__weak typeof(self)weakSelf = self;
avatar.frame = ({
__strong typeof(weakSelf)strongSelf = weakSelf;
CGRect frame = avatar.frame;
frame.origin.y = CGRectGetMaxY(strongSelf.view);
frame;
});
It's not a block. It is an GCC C extension, which causes a code block
to return a value if enclosed within brackets and parentheses.
This not only segregates configuration details into initialization,
but the additional scope allows generic variable names like frame,
button, and view to be reused in subsequent initializations. No more
loginButtonFrame = ... / signupButtonFrame = ...!
source: http://nshipster.com/new-years-2014/
This is not a block, block start with ^.
I believe this code:
({
CGRect frame = avatar.frame;
frame.origin.y = CGRectGetMaxY(self.view);
frame;
});
Is a way to create a CGRect.

Creating object programmatically and changing that object's position

I am trying to create a couple of UIImageViews (preferably with a for loop) and then afterwards move them, but I don't know how because I'm having trouble figuring out how to reference them if they will be made programmatically.
So I want something like this:
for (int i = 0; i < 2; i++)
{
UIImageView *iv = [[UIImageView alloc]initWithImage:[UIImage imageNamed: picturo]];
CGRect rect = CGRectMake((i * 50) + 50,30, 25, 25);
[iv setFrame:rect];
iv.tag = i;
[self.view addSubview:iv];
}
(iv with tag of 0).center.y = 80; // <-- How do I do that!!
Obviously this example has no practical use and I could just change y value of 'rect' above to 80, but I want to know how to:
a. Create multiple uiimageviews (or any object for that matter) and be able to identify/reference/manipulate each one individually (I don't know how but I would assume by either naming them uniquely or using tags) and
b. Be able to identify/reference/manipulate an object that was created programmatically.
creating views with tags works the way you have it.
To access those views use the viewWithTag property on a view to identify one of it's subviews:
UIView* subview = [self.view viewWithTag:0];
subview.center = CGPointMake(subview.center.x, 80);
(you cannot write to a view.center's x or y, you have to recreate the whole thing. Likewise with other geometric structs such as CGSize, CGRect)

Resources