Im sure that it will be a simple and obvious fix, but I cannot see why this occurs.
Basically I want to code a button to change its background colour, depending on what the colour is at the present. The following code works but it uses the UI Colours in xcode.
-(IBAction)Button1Colour:(id)sender{
if (_Button1.backgroundColor == nil) {
_Button1.backgroundColor = [UIColor orangeColor];}
else if (_Button1.backgroundColor == [UIColor orangeColor]) {
_Button1.backgroundColor = [UIColor greenColor];}
else (_Button1.backgroundColor = nil);}
Now if I use RGB colours as follows:
-(IBAction)Button1Colour:(id)sender{
if (_Button1.backgroundColor == nil) {
_Button1.backgroundColor = [UIColor colorWithRed:(216/255.f) green:(146/255.f) blue:(48/255.f) alpha:0.3];}
else if (_Button1.backgroundColor == [UIColor colorWithRed:(216/255.f) green:(146/255.f) blue:(48/255.f) alpha:0.3]) {
_Button1.backgroundColor = [UIColor colorWithRed:(33/255.f) green:(141/255.f) blue:(8/255.f) alpha:0.3];}
else (_Button1.backgroundColor = nil);}
The button will only cycle from nil to amber to nil etc missing out the else if statement.
Any advice or help would be much appreciated
You're trying to determine whether the button is a particular color by comparing 3 sets of floating point numbers.
The second if test is failing because you can't compare CGFloats for exact equality.
The easier way is to subclass your button and add a BOOL property indicating whether it's "toggled" or not. Then you can check the property and simply change between one color and the next.
Assuming the property you add is called green, it would look like this
#property (assign, getter=isGreen) BOOL green;
and you could more concisely change the color like so
Button1.backgroundColor = [Button1 isGreen] ? [UIColor orangeColor] : [UIColor greenColor];
Button1.green = !Button1.green;
As an aside, naming conventions suggest that a class starts with a capital letter, e.g. UIButton. An instance variable starts with a lowercase letter, e.g. button1.
Related
I am trying to make an MKPolyline for a SwiftUI map where it shows a persons location for a day and I want a gradient changing from blue to green from the first point in their location to the last point in blue. I have this code
renderer.strokeColor = NSGradient(colors: [NSColor.blue, NSColor.green])
I have also tried
renderer.strokeColor = NSColor(NSGradient(colors: [NSColor.blue, NSColor.green]))
and
renderer.strokeColor = NSColor(Color(Gradient(colors: [Color.blue, Color.green])))
but these all return errors about turning Gradients into colors. Thanks!
Thanks to #vadian I did this
if let routePolyline = overlay as? MKPolyline {
let renderer = MKGradientPolylineRenderer(polyline: routePolyline)
renderer.setColors([NSColor.blue, NSColor.green], locations: [])
renderer.lineWidth = 2
return renderer
}
Let say I have a SwiftUI component and I want it to change color according to a parameter I choose like :
Component(colorValue: "1")
Component(colorValue: "2")
Component(colorValue: "3")
colorValue: 1 would change the color of my component to red, 2 to green, 3 to blue for example.
When I only had 2 colors in the beggining of my project I used a boolean in my component :
Rectangle().fill(Color(colorValue ? "red" : "blue"))
But now that I have multiple choice, how can I achieve the color change by checking the value of the colorValue String ?
Thanks in advance !
just use a function
func getColorValue() -> Color {
if colorValue == 1 { return .red }
// and so on
}
Rectangle().fill(Color(getColorValue()))
I am building SDL2 applications for macOS using C++. I need some "basic" scrolling for an app (like a web browser). I achieve that using the SDL_MouseWheel event, which gives me a fully functional "windows-like" scrolling. I am using a Macbook Pro and I want to bring the trackpad's functionality in.
Simply, I am asking for a better scrolling algorithm (Macbook's trackpad scrolling, inertial scrolling)
I know about the SDL_MultiGesture event, but I don't really know how to put things together to achieve the result I want.
I ran into the same issue, and it turns out that SDL opts out of momentum scroll events by turning off the AppleMomentumScrollSupported default in the user defaults system.
You can turn this back on in your application with the following bit of Objective-C++, and your SDL_MouseWheel events will become smoothed.
NSDictionary *appDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], #"AppleMomentumScrollSupported",
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
[appDefaults release];
Okay, here's the answer to the problem.
First of all, you will have to do it manually.
I also assume that you know SDL2 and C++.
*Note: I'm doing scrolling only for Y-Axis (you can do it for both if you want).
Firstly we will need some variables:
int scrolling; // flag (scrolling or not)
int scroll_sensitivity = 40; // how fast we want to scroll
double scroll_Y = 0; // current scrolling amount (on Y-Axis)
double scroll_acceleration; // scrolling speed
double scroll_friction = 0.001; // how fast we decelerate
double scroll_prev_pos; // previous event's position
After that you will need to handle the SDL_MultiGesture event:
case SDL_MULTIGESTURE:{
if(event.mgesture.numFingers == 2){
if(scrolling == 0){
scrolling = 1;
scroll_prev_pos = event.mgesture.y;
} else{
double dy = event.mgesture.y - scroll_prev_pos;
scroll_acceleration = dy * 40;
scroll_prev_pos = event.mgesture.y;
scrolling = 1;
}
}
break;
}
Also, we need to stop scrolling on SDL_FingerDown event:
case SDL_FINGERDOWN:{
scrolling = 0;
break;
}
Next, we want to update scroll_Y (put it in your "update" function):
if(scrolling){
if(scroll_acceleration > 0) scroll_acceleration -= scroll_friction;
if(scroll_acceleration < 0) scroll_acceleration += scroll_friction;
if(abs(scroll_acceleration) < 0.0005) scroll_acceleration = 0;
scroll_Y += scroll_sensitivity * scroll_acceleration;
// Here you have to set your scrolling bounds i.e. if(scroll_Y < 0) scroll_Y = 0;
}
Finally, we want to render according to our scroll values:
SDL_Rect rect = {some_x, some_y + scroll_Y, some_w, some_h};
SDL_RenderCopy(renderer, some_texture, NULL, &rect);
This is it!
I have a fully working app with the above code, so I'm 100% sure that this works as supposed. If you have any problems (because it's not actual code, it's more like an algorithm) contact me. As I mentioned before, I assume that you already know good enough SDL and C++, so I believe that you are able to understand the implementation.
Also, I know that this solution can become better, so if you have anything to add / change, just say it!
Have a nice day!
For some reason, #Aleski's answer doesn't work anymore. The new way to hack this feature back on is:
[[NSUserDefaults standardUserDefaults] setBool: YES
forKey: #"AppleMomentumScrollSupported"];
I have found very little documentation when it comes to the C++ Feature Pack and all the examples I have found all are the same example. The problem I am experiencing involves EnableAutomaticButton in the color panel. If I set the default color to black as in the following code clicking the button makes the color white (ffffff). After checking the return value I found it is returning -1 so in other words FALSE and does not return black but everything else returns correctly even the color chips in the popup box.
CMFCPropertyGridProperty* pGroup2 = new CMFCPropertyGridProperty(_T("View"));
CMFCPropertyGridColorProperty* pColorProp = new CMFCPropertyGridColorProperty(_T("Color"), RGB(0, 0, 0), NULL, _T("Specifies the default View color"));
pColorProp->EnableOtherButton(_T("Other..."),TRUE,TRUE);
pColorProp->EnableAutomaticButton(_T("Default"),RGB(0,0,0),TRUE);
pColorProp->SetColor(RGB(0,0,0));
pColorProp->SetColumnsNumber(5);
pGroup2->AddSubItem(pColorProp);
yes, GetColor(); return -1 for automatic selection. So try something like;-
m_Colour = m_ColourBut.GetColor();
// Handle the default colour selection.
if (m_Colour == -1)
{
m_Colour = m_ColourBut.GetAutomaticColor();
}
I have one question when infinite background scrolling is done, is the object remain fixed(like doodle in doodle jump, papy in papi jump) or these object really moves.Is only background move or both (background and object )move.plz someone help me.I am searching for this solution for 4/5 days,but can't get the solution.So plz someone help me. And if object does not move how to create such a illusion of object moving.
If you add the object to the same layer as the scrolling background, then it will scroll as the background scrolls.
If your looking for an effect like the hero in doodle jump, you may want to look at having two or more layers in a scene.
Layer 1: Scrolling Background Layer
Layer 2: Sprite layer
SomeScene.m
CCLayer *backgroundLayer = [[CCLayer alloc] init];
CCLayer *spriteLayer= [[CCLayer alloc] init];
[self addChild:backgroundLayer z:0];
[self addChild:spriteLayer z:1];
//Hero stays in one spot regardless of background scrolling.
CCSprite *squidHero = [[CCSprite alloc] initWithFile:#"squid.png"];
[spriteLayer addChild:squidHero];
If you want objects to scroll with the background add it to the background layer:
//Platform moves with background.
CCSprite *bouncePlatform= [[CCSprite alloc] initWithFile:#"bouncePlatform.png"];
[backgroundLayer addChild:bouncePlatform];
Another alternative is to use a CCFollow action. You would code as if the background is static (which it will be) and the player is moving (which it will be), but add a CCFollow action to the player. This essentially moves the camera so that it tracks your player.
You can also modify the classes so that you can get the CCFollow action to follow with an offset (i.e., so the player is not in the middle of the screen) as well as to have a smoothing effect to it, so that when the player moves, the follow action is not jerky. See the below code:
*NOTE I am using cocos2d-x, the c++ port. The methods are similar in cocos2d, and you should be able to modify these to fit the cocos2d syntax. Or search around -- I found these for cocos2d and then ported to c++.
//defines the action to constantly follow the player (in my case, "runner.p_sprite is the sprite pointing to the player)
FollowWithOffset* followAction = FollowWithOffset::create(runner.p_sprite, CCRectZero);
runAction(followAction);
And separately, I have copied the class definition for CCFollow to create my own class, CCFollowWithAction. This also has a smoothing effect (you can look this up more online) so that when the player moves, the actions are not jerky. I modified "initWithTarget," to take into account an offset, and "step," to add a smoothing action. You can see the modifications in the comments below.
bool FollowWithOffset::initWithTarget(CCNode *pFollowedNode, const CCRect& rect/* = CCRectZero*/)
{
CCAssert(pFollowedNode != NULL, "");
pFollowedNode->retain();
m_pobFollowedNode = pFollowedNode;
if (rect.equals(CCRectZero))
{
m_bBoundarySet = false;
}
else
{
m_bBoundarySet = true;
}
m_bBoundaryFullyCovered = false;
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
m_obFullScreenSize = CCPointMake(winSize.width, winSize.height);
//m_obHalfScreenSize = ccpMult(m_obFullScreenSize, 0.5f);
m_obHalfScreenSize = CCPointMake(m_obFullScreenSize.x/2 + RUNNER_FOLLOW_OFFSET_X,
m_obFullScreenSize.y/2 + RUNNER_FOLLOW_OFFSET_Y);
if (m_bBoundarySet)
{
m_fLeftBoundary = -((rect.origin.x+rect.size.width) - m_obFullScreenSize.x);
m_fRightBoundary = -rect.origin.x ;
m_fTopBoundary = -rect.origin.y;
m_fBottomBoundary = -((rect.origin.y+rect.size.height) - m_obFullScreenSize.y);
if(m_fRightBoundary < m_fLeftBoundary)
{
// screen width is larger than world's boundary width
//set both in the middle of the world
m_fRightBoundary = m_fLeftBoundary = (m_fLeftBoundary + m_fRightBoundary) / 2;
}
if(m_fTopBoundary < m_fBottomBoundary)
{
// screen width is larger than world's boundary width
//set both in the middle of the world
m_fTopBoundary = m_fBottomBoundary = (m_fTopBoundary + m_fBottomBoundary) / 2;
}
if( (m_fTopBoundary == m_fBottomBoundary) && (m_fLeftBoundary == m_fRightBoundary) )
{
m_bBoundaryFullyCovered = true;
}
}
return true;
}
void FollowWithOffset::step(float dt)
{
CC_UNUSED_PARAM(dt);
if(m_bBoundarySet){
// whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
if(m_bBoundaryFullyCovered)
return;
CCPoint tempPos = ccpSub( m_obHalfScreenSize, m_pobFollowedNode->getPosition());
m_pTarget->setPosition(ccp(clampf(tempPos.x, m_fLeftBoundary, m_fRightBoundary),
clampf(tempPos.y, m_fBottomBoundary, m_fTopBoundary)));
}
else{
//custom written code to add in support for a smooth ccfollow action
CCPoint tempPos = ccpSub( m_obHalfScreenSize, m_pobFollowedNode->getPosition());
CCPoint moveVect = ccpMult(ccpSub(tempPos,m_pTarget->getPosition()),0.25); //0.25 is the smooth constant.
CCPoint newPos = ccpAdd(m_pTarget->getPosition(), moveVect);
m_pTarget->setPosition(newPos);
}
}