I am making a simple 'Simon Says' style app in Swift and I would like to flash buttons to show the sequence the user has to follow.
I have made this function which iterates over an array of the buttons to just change the background colour for now.
func animateButtons() {
for (index, button) in buttonSequence.enumerated() {
UIButton.animate(withDuration: 1, delay: TimeInterval(index)) {
button.backgroundColor = UIColor(red: 63/255, green: 255/255, blue: 0/255, alpha: 1.0)
button.backgroundColor = UIColor(red: 168/255, green: 61/255, blue: 164/255, alpha: 0.85)
}
}
}
Right now though when the function is called it lights up all the buttons at once but animates them returning back to their normal colour one by one. Ideally I want it to animate one button completely, then the next etc.
I looked into using a Timer for this but couldn't find exactly how to use it properly when searching documentation.
The problem with your code is that you set the button color to 2 different values inside your animation block. The first color will be overridden and have no effect.
If you want each button to change to the first color in your animation block, hold for 1 second, and then revert to the 2nd color, change your code like this:
func animateButtons() {
for (index, button) in buttonSequence.enumerated() {
UIButton.animate(
withDuration: 1,
delay: TimeInterval(index),
animations: {
button.backgroundColor = UIColor(red: 63/255, green: 255/255, blue: 0/255, alpha: 1.0)
},
completion: { finished in
button.backgroundColor = UIColor(red: 168/255, green: 61/255, blue: 164/255, alpha: 0.85)
}
)
}
}
Related
I need to only show two shapes in my custom Tui image editor, a rectangle and a circle, nothing more nothing less.
I added the rectangle and it works perfectly but if I add another function to add a circle and draw either or first the and then select the other, it still draws the first item. (if you click on a circle and draw, then click on the rectangle and draw then it draws a circle)
I am not sure how I can get this to function properly.
here is my two functions for my circle and rectangle.
const onAddCircle = () => {
imageEditorRef.current.startDrawingMode('SHAPE');
if (imageEditorRef.current.getDrawingMode() !== 'SHAPE') {
const { height } = imageEditorRef.current.getCanvasSize();
imageEditorRef.current.startDrawingMode('SHAPE');
imageEditorRef.current.setDrawingShape('circle', {
fill: 'transparent',
stroke: COLOR_STATUS_ORANGE,
strokeWidth: height / 100,
isRegular: true,
});
}
};
const onAddRectangle = () => {
if (imageEditorRef.current.getDrawingMode() !== 'SHAPE') {
const { height } = imageEditorRef.current.getCanvasSize();
imageEditorRef.current.startDrawingMode('SHAPE');
imageEditorRef.current.clearObjects();
imageEditorRef.current.setDrawingShape('rect', {
fill: 'transparent',
stroke: COLOR_STATUS_ORANGE,
strokeWidth: height / 100,
isRegular: true,
});
}
};
and they are triggered by buttons
<button
onClick={onAddCircle}
color="green"
/>
<button
onClick={onAddRectangle}
color="red"
/>
I've tried adding imageEditorRef.current.clearDrawingShape(); to the beginning of the functions but it says its not a function because it doesn't exist. then I tried adding imageEditorRef.current.clearObjects(); but that clears everything that it draw by that shape.
I've looked their documentation as well and there is nothing on how to actually clear shape cache before drawing or selecting another shape.
Could someone please help ?
I fixed it!
Ive combined both functions into one added a prop called shape, and it checks if the prop is set to either or and then if it is then it uses that logic else it clears the drawing board.
const drawShape = (Shape) => {
const { height } = imageEditorRef.current.getCanvasSize();
imageEditorRef.current.startDrawingMode('SHAPE');
if (Shape === 'circle') {
imageEditorRef.current.setDrawingShape('circle', {
fill: 'transparent',
stroke: COLOR_STATUS_ORANGE,
strokeWidth: height / 100,
isRegular: true,
});
} else if (Shape === 'rectangle') {
imageEditorRef.current.setDrawingShape('rect', {
fill: 'transparent',
stroke: COLOR_STATUS_ORANGE,
strokeWidth: height / 100,
isRegular: true,
});
} else {
imageEditorRef.current.stopDrawingMode();
}
};
By setting fill property we can set the background color property of the zoom controls, but the button text color is not a property we can set.
chart.zoomControl.plusButton.background.cornerRadius(5, 5, 5, 5);
chart.zoomControl.plusButton.background.fill = '#014888';
chart.zoomControl.plusButton.background.states.getKey('hover').properties.fill = '#27aad6';
Is there a choice to set it?
I have set it by this way:
chart.zoomControl.plusButton.label.fill = '#ffffff';
chart.zoomControl.minusButton.label.fill = '#ffffff';
chart.set("zoomControl", am5map.ZoomControl.new(root, {
background: am5.Rectangle.new(root, {
// fill: am5.color(0xeb354e),
fillOpacity: 0.9,
strokeOpacity:0
})
}));
I am currently using Viro-React (React-Viro) for a AR project in which, if a certain pictures gets seen by the camera a video is played infront of it. I had it working perfectly, but somehow and a few days later, without changing the code, the video and everything inside the ViroARImageMarker is always positioned inside the camera, when the target gets seen.
This behavior only seems to happen in my own projects and not in the samples provided by Viro Media.
I have tried to:
Reinstalling node modules
Compared the package.json's and reinstalled.
Changed the position of the elements inside the ViroARImageMarker
And reorganised the elements.
But nothing seems to work.
As I said the code itself shows and hides the video, but does not position the video (every inside the ViroARImageMarker correctly, but positions them in the position of the camera when the targets gets seen and then keeps them there.
Here is the code. (Snippet at the end)
I pass this function to the ViroARSceneNavigator in another script.
There are a few animations, which just scale up/down the video depending if the target is in view or not.
(I removed the whitespaces to fit more onto one screen)
Main Code
Viro Animations and Material
"use strict";
import React, { useState } from "react";
import { ViroARScene, ViroNode, ViroARImageMarker, ViroVideo, ViroARTrackingTargets, ViroAnimations, ViroMaterials } from "react-viro";
const MainScene = (props) => {
const videoPath = require("./res/Test_Video.mp4");
const [playVideoAnimation, setPlayVideoAnimation] = useState(false);
const [videoAnimationName, setVideoAnimationString] = useState("showVideo");
const [shouldPlayVideo, setShouldPlayVideo] = useState(false);
function onAnchorFound() {
setPlayVideoAnimation(true);
setVideoAnimationString("showVideo");
setShouldPlayVideo(true);
}
function onAnchorRemoved() {
setShouldPlayVideo(false);
setVideoAnimationString("closeVideo");
setPlayVideoAnimation(true);
}
function onVideoAnimationFinish() {
setPlayVideoAnimation(false);
}
function onVideoFinish() {
setShouldPlayVideo(false);
setVideoAnimationString("closeVideo");
setPlayVideoAnimation(true);
}
return (
<ViroARScene>
<ViroARImageMarker target={"targetOne"} onAnchorFound={onAnchorFound} onAnchorRemoved={onAnchorRemoved}>
<ViroNode rotation={[-90, 0, 0]}>
<ViroVideo
position={[0, 0, 0]}
scale={[0, 0, 0]}
dragType="FixedToWorld"
animation={{ name: videoAnimationName, run: playVideoAnimation, onFinish: onVideoAnimationFinish }}
source={videoPath}
materials={["chromaKeyFilteredVideo"]}
height={0.2 * (9 / 16)}
width={0.2}
paused={!shouldPlayVideo}
onFinish={onVideoFinish}
/>
</ViroNode>
</ViroARImageMarker>
</ViroARScene>
);
};
ViroAnimations.registerAnimations({
showVideo: {
properties: { scaleX: 0.9, scaleY: 0.9, scaleZ: 0.9 },
duration: 1,
easing: "bounce",
},
closeVideo: {
properties: { scaleX: 0, scaleY: 0, scaleZ: 0 },
duration: 1,
},
});
ViroMaterials.createMaterials({
chromaKeyFilteredVideo: {
chromaKeyFilteringColor: "#00FF00",
},
});
ViroARTrackingTargets.createTargets({
targetOne: {
source: require("./res/Test_Bild.png"),
orientation: "Up",
physicalWidth: 0.01, // real world width in meters
},
});
export default MainScene;
I was able to resolve the issue by copying (downgrading) my dependencies in my package.json from the React-Viro codesamples and decreasing the width/height (inside the element) and scale (in the animation) of the video.
Note that if the sub element of the ViroARImageMarker is too big (in scale and size), the issue comes back.
how can I do fade in and out when button is pressed.
I am looking for most simple and best practice Swift 4 solution as possible.
Something like Apple iOS 11 Calculator button fade...
So far I have this...
myButton.setTitleColor(UIColor.red, for: UIControlState.normal)
myButton.backgroundColor=UIColor.gray
myButton.setTitleColor(UIColor.gray, for: UIControlState.highlighted)
myButton.backgroundColor=UIColor.red
I am kinda lost. Many thanks for any answer.
I don't know about fade in/out for calculator but you will get similar effect by this:
Set UIButton type as Custom and set Text Color as White from storyboard.
Set BackgroundColor of UIButton as Tungsten(take e.g. Calculator app)
Create custom class for UIButton and set customButton class to UIButton from Identity Inspector.
class customButton: UIButton {
override open var isHighlighted: Bool {
didSet {
//Set colors for Highlighted & Unhighlighted
backgroundColor = isHighlighted ? UIColor.lightGray.withAlphaComponent(0.7) : UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 1.0)
}
}
}
Result:
I just updated to Xcode 9 and run to an iOS11 simulator. My custom view for the navaagation bar title is shifted down.
This code was working before i updated; it was vertically centered before
companyCountryView = CompanyNameView(frame: CGRect(x: 0, y: 0, width: Utils.getScreenWidth() - 150, height: 35))
companyCountryView.companyLbl.text = ""
companyCountryView.countryLbl.text = ""
self.navigationItem.titleView = companyCountryView
Even though I change values for y and height, no effect at all.
It seems the width value i used does not do any effect too.
I have solved it! You need to override the intrinsicContentSize in your custom view class and put the size of the view there:
class CustomView: UIView {
override var intrinsicContentSize: CGSize {
return CGSize(width: Utils.getScreenWidth() - 150.0, height: 35.0)
}
}