binding.card1.setOnClickListener {
binding.card1Text.setBackgroundResource(R.drawable.background_2)
binding.card3.setOnClickListener {
Handler().postDelayed({
binding.card1Text.setBackgroundResource(R.drawable.option_true)
binding.card3Text.setBackgroundResource(R.drawable.option_true)
},3000)
}
binding.card2.setOnClickListener {
binding.card1Text.setBackgroundResource(R.drawable.option_wrong)
binding.card2Text.setBackgroundResource(R.drawable.option_wrong)
Handler().postDelayed({
binding.card1Text.setBackgroundResource(R.drawable.background_3)
binding.card2Text.setBackgroundResource(R.drawable.background_3)
},3000)
}
}
I have cardviews as seen in the figure. I will pair them with each other. Matches will light up the same color, if they are not, they will light red. The point I am stuck on is that after clicking on the 1st cardview, I want to check whether it matches or not when I click on any cardview. but I couldn't do that. I found the solution as just to control the click of all of them one by one inside that cardview onclick method. This will create redundant code. Is it possible to shorten it?
enter image description here
Related
I'm starting to learn swiftui and I've run into a problem that is both very basic and easily solvable in UIKit; but after spending days searching the internet and watching WWDC videos I've found no native solution.
The premise is simple: I have an array of songs I want to display in a list; when a user taps on a song view it should highlight the view on press, unhighlight after release, and then play the song (ie trigger an action). Sounds simple right?
Here's what I tried and spent way too much time on:
Using List(selection) + .onEvent(changed): I end up with a UUID (because i've only gotten selection to work with a UUID) that I then have to check against an array of songs to match AND the cell won't unhighlight/select itself; even when I try to manually set the State variable to nil or another generated UUID.
Using .onTap (either on or in the cell): I have to tap on the text of the cell to trigger onTap so I get a lot of taps that just don't work (because I have lots of white space in the cell). I also don't get a nice UI color change on press/release.
So after spending hours trying many different things I've finally come up with a solution and I basically wanted to create an account and share it to hopefully help other developers in my position. Because this so very annoyed me that something so basic took so much effort and time to do.
In the end the best solution I came up with was this:
Using ZStack and an empty button:
edit: I found I need to include and hide the content otherwise the button doesn't grow to fill the space (seems in lists it does for some reason). Though not sure what the hit on performance is of rendering the content twice when hiding it. Maybe a GeometryReader would work better?
struct SelectionView: ViewModifier {
let onSelect: () -> Void
func body(content: Content) -> some View {
ZStack (alignment: .leading) {
Button {
onSelect()
} label: {
content
.hidden()
}
content
}
}
}
extension View {
func onSelection(_ selection: #escaping () -> Void) -> some View {
self.modifier(SelectionView(onSelect: selection))
}
}
then to use it:
SongCell(song: song)
.onSelection {
// Do whatever action you want
}
No messing around with list selection, no weird tap hit boxes, and get the press/release color change. Basically put an empty button in a ZStack and trigger off it's action. Could possibly cause tap/touch issues with more complicated cells (?) but it does exactly what I need it to do for my basic app. I'm just not sure why it took so much effort and why apple doesn't support such a basic use case by default? If I've overlooked something native please do inform me. Thanks.
I got the basic idea what you are trying to do. I'm Going to show simple example. Maybe using this you will be able to find proper solution.
First let's create a color : -
#State var colorToShow : Color = Color.blue
Now in body we have our ZStack or Your cell that we want to deal with : -
ZStack{
colorToShow
}.frame(width: 50, height: 50).padding()
.onLongPressGesture(minimumDuration: 3) {
print("Process Complete")
colorToShow = .green
} onPressingChanged: { pressing in
if pressing {
print("Pressing")
colorToShow = .red
} else {
print("Pressing Released")
colorToShow = .blue
}
}
Here we are using .onLongPressGesture. You can set minimum duration on which you want to perform action. Now on process completion You set what you want to do. OnPressingChange give you a bool value that changes according to user is pressing that button or not. Show color change(Highlight) or do action while bool value is true. When user release button do action or unhighlight since bool value turns false.
Hope you find it useful.
I have just updated my code to use the latest 2.4.0-alpha05 for the navigation component and I have custom navigation between the multiple stacks and my main nav graph is like the documentation I found.
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="#+id/accounts"
android:id="#+id/bottom_nav">
<inclue app:graph="#navigation/accounts_tab_nav"/>
<include app:graph="#navigation/contact_tab_nav" />
<include app:graph="#navigation/profile_tab_nav" />
</navigation>
Most of my stacks animate with a slide from right to left. It looks like that when I am on the second screen, in let's say the profile screen, and then switch to the first tab it triggers the popEnter en popExitAnim that are defined in the action that leads to the second screen in the profile tab. Like so:
<fragment
android:id="#+id/profileMain"
android:name="com.app.ProfileFragment"
tools:layout="#layout/fragment_profile">
<action
android:id="#+id/action_profileMain_to_secondFragment"
app:destination="#id/secondFragment"
app:enterAnim="#anim/slide_in_right"
app:exitAnim="#anim/slide_out_left"
app:popEnterAnim="#anim/slide_in_left"
app:popExitAnim="#anim/slide_out_right" />
</fragment>
But obviously I want tho use the (default) fade animation when switching tabs. So how should I do that?
And I would like to pop to the root of the stack when reselecting a tab. But I probably have to do that myself?
I came up with a solution that seems to work for me, but I have to admit it feels a little bit hacky.
I have a public flag in my MainActivity:
var tabWasSelected = false
Then I remember if a tab item was selected in setOnItemSelectedListener
// always show selected Bottom Navigation item as selected (return true)
bottomNavigationView.setOnItemSelectedListener { item ->
// In order to get the expected behavior, you have to call default Navigation method manually
NavigationUI.onNavDestinationSelected(item, navController)
// set flag so that the fragment can call the correct animation on tab change in onCreateAnimation
tabWasSelected = true
return#setOnItemSelectedListener true
}
This will always select the item and navigate to the associated destination while maintaining multiple back stacks.
I then have created a Fragment class which all my other fragments inherit from. It simply overrides onCreateAnimation to set the correct animation. Here is what it looks like:
open class MyFragment: Fragment() {
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
val activity = requireActivity()
if (activity is MainActivity) {
if (activity.tabWasSelected) {
if (enter) {
//flow is exit first, then enter, so we have to reset the flag on enter
//in order that following animations will run as defined in the nav graph
activity.tabWasSelected = false
return AnimationUtils.loadAnimation(requireContext(), R.anim.nav_default_pop_enter_anim)
} else {
return AnimationUtils.loadAnimation(requireContext(), R.anim.nav_default_pop_exit_anim)
}
}
}
//no tab was selected, so run the defined animation
return super.onCreateAnimation(transit, enter, nextAnim)
}
}
Instead of using setupWithNavController function, follow this way.
First, create your NavOptions which include animation shown below.
val options = NavOptions.Builder()
.setLaunchSingleTop(true)
.setEnterAnim(R.anim.enter_from_bottom)
.setExitAnim(R.anim.exit_to_top)
.setPopEnterAnim(R.anim.enter_from_top)
.setPopExitAnim(R.anim.exit_to_bottom)
.setPopUpTo(navController.graph.startDestination,false)
.build();
Then use setOnNavigationItemSelectedListener to navigate with animation like that.
bottomNavigationView.setOnNavigationItemSelectedListener
{ item ->
when(item.itemId) {
R.id.fragmentFirst -> {
navController.navigate(R.id.fragmentFirst,null,options)
}
R.id.fragmentSecond -> {
navigate(R.id.fragmentSecond,null,options)
}
R.id.fragmentThird -> {
navController.navigate(R.id.fragmentThird,null,options)
}
}
}
Finally, you should prevent same item selection case so you can add below code.
bottomNavigationView.setOnNavigationItemReselectedListener
{ item ->
return#setOnNavigationItemReselectedListener
}
I used bottomNavigation like that in my project to add animation for page transitions. I hope it helped.
Hello I want to create some buttons with SFML-IMGUI and after that relate to them in some way for example to change text. How can I do this? I dont see any ID attribute. I create button using this code.
ImGui::Begin("Button");
Button("Click me");
End();
I dont see any example in documentation :/
Imgui buttons don't use any id or callbacks. Instead, the ImGui::Button("Clikc me") will return a boolean which is true if the button was clicked. (here is an example)
ImGui::Begin("window");
if (ImGui::Button("Click me")) {
// onButtonClick();
}
ImGui::End();
for more read https://github.com/ocornut/imgui/tree/master/docs and seeimgui_demo.cpp it has some better examples on how to use it.
I'd like to append a new menu entry right below "Enter Full Screen", but I am failing to find the right CommandGroupPlacement property.
CommandGroup(after: .<what needs to be put here??>) {
//my buttons here
}
Attempting to override "View" results in just another group with the same name (see image).
CommandMenu("View") {
//add button here
}
Shoutout to Majid Jabrayilov for his blogpost on this: https://swiftwithmajid.com/2020/11/24/commands-in-swiftui/
To find a solution to my above issue though I still had to think a bit around the corner–what does work is this:
CommandGroup(before: .toolbar) {
Button("Foo") {
}
}
This works, because the toolbar menu entry is located within "View" (even thought I don't have a toolbar in my app, the placement still works nonetheless...)
You said you were looking for the proper CommandGroupPlacement so for your case (relative to full screen mode), you would technically want CommandGroupPlacement.sidebar. CommandGroupPlacement.toolbar works because toolbar options live in the View menu, though you have none set.
/// Example in a CommandsBuilder
CommandGroup(after: CommandGroupPlacement.sidebar) {
Button("New View Action", action: { print("After sidebar menu options") }).keyboardShortcut("s", modifiers: [.command, .option, .control, .function]
}
This should also come in handy for others. The Apple documentation that corresponds to this: CommandGroupPlacement
I have 3 radio buttons and a spinbox. Each radio button is supposed to chnage the spinboxes value to inches, feet or meters respectively. How would i do that? I would have to know which radio button was active last, right? Could someone give me some example code please?
Radio Button and check boxes hold their state as value, and expose it to your user. You can call isChecked() to know the state of your member variable radio button. Something like
void some_button_hit(bool checked)
{
if (inches.isChecked()) {...}
else if (feet.isChecked()) {...}
else if (meters.isChecked()) {...}
}
and 'wire' the event toggled from any of these. This is usually done in initialization,
using the form editor, or via connect.
Using the form editor, right click on a radio button, and follow goto slot...
The editor build and connect the event handler:
void GroupBox::on_feet_toggled(bool checked)
{
ui->label->setText("feet");
}
void GroupBox::on_inches_toggled(bool checked)
{
ui->label->setText("inches");
}
void GroupBox::on_meters_toggled(bool checked)
{
ui->label->setText("meters");
}