How to get IOS like look and feel in QML Style - ios

I'm trying to port an iPad application from QT 5.12.11 to QT 6.4.2, and I cant get the UI to look as it was before.
this is the look I want with native IOS styled dropdown and feel (which I am getting in Qt 5.12.11)
this is the look I currently have
I have tried import QtQuick.Controls.iOS but still my dropdown doesn't look like native IOS like [https://www.qt.io/blog/qt-quick-controls-2-ios-style]
I have tried import QtQuick.Controls.Material and import QtQuick.Controls.Universal but still my dropdown doesn't look as expected.
My code is as follow:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Rectangle {
Flickable{id: playerEdit
// ...
Rectangle { id: playerEditCanvas
// ...
Column { id: playerEditColumn
// ...
Rectangle { id: playerEditPrimaryDetailsRow
// ...
Column { id: playerEditDemoColumn
// ...
Rectangle { id: playerEditAccount
Text {
text: "account"
anchors.fill: parent
font {
family: "SF UI Display"
styleName: "Light"
pixelSize: 14
}
color: "#0077fe"
verticalAlignment: Text.AlignVCenter
}
ComboBox { id: playerEditAccountField
width: 501
height: 42
anchors.left: playerEditAccountLabel.right
anchors.leftMargin: 1
textRole: "rostername"
model: ListModel { id: playerEditAccountModel
Component.onCompleted: {// ...}
}
}
}
// ...
}
// ...
}
// ...
}
// ...
}
// ...
}
// ...
}

If you want to achieve that same look, you will have to use the Menu from the Qt Quick Labs module: https://doc.qt.io/qt-6/qml-qt-labs-platform-menu.html, which will draw a native picker, like the one you want.
The ComboBox implementation for the iOS style doesn't use a picker, but pops a menu instead, similar to pull-downs in iOS: https://i.stack.imgur.com/FiWa9.png

I think you want Tumbler (see https://doc.qt.io/qt-6/qml-qtquick-controls2-tumbler.html).
In the following example, I customized ComboBox popup replacing it with a customized one based on Tumbler. I added customizations, like hardcoding the position to be relative to my parent Page making relative references to myApp. I also added Cancel and Done buttons based on your screenshot. I am not a native iOS person, so, I am judging the UI/UX based on the screenshots you've supplied.
import QtQuick
import QtQuick.Controls
Page {
id: myApp
AppComboBox {
model: [
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December"
]
}
}
// AppComboBox.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ComboBox {
id: appComboBox
popup: Popup {
id: popup
y: myApp.height - height
width: myApp.width
height: myApp.height / 2
padding: 0
background: Rectangle { color: "#eee" }
ColumnLayout {
anchors.fill: parent
spacing: 0
Frame {
Layout.fillWidth: true
background: Rectangle {
color: "#ddd"
border.color: "#aaa"
}
padding: 1
RowLayout {
width: parent.width
Button {
text: qsTr("Cancel")
palette.buttonText: "#08f"
onClicked: popup.close()
}
Button {
Layout.alignment: Qt.AlignRight
palette.buttonText: "#08f"
text: qsTr("Done")
onClicked: {
appComboBox.currentIndex = tumbler.currentIndex;
popup.close()
}
}
}
}
Frame {
Layout.fillWidth: true
Layout.fillHeight: true
padding: 1
Tumbler {
id: tumbler
anchors.fill: parent
model: appComboBox.model
currentIndex: appComboBox.currentIndex
}
}
}
}
}
You can Try it Online!
You may also want to check out what's Qt Quick Controls 2: iOS Style in Qt6.4 - https://www.qt.io/blog/qt-quick-controls-2-ios-style

Related

Qt/Qml - Press n hold the space bar - use your iphone space bar like a mouse

Is it possible to get such cursor control in QML TextArea?
for example, a video on this topic
https://www.youtube.com/watch?v=XRUCnZFv9Ro
Because Qt now encourages you to use QtQuick 2.x controls instead of QtQuick 1.x controls interactions need to be recreated in the Qt environment, and you can no longer rely on the OS to do this for you. Unfortunately, the user interaction you describe would take some effort to recreate.
To start, the following code only does the first part: intercepts the long press of a space. The second part had not been implemented, i.e. the handling of mouse drag:
import QtQuick
import QtQuick.Controls
Page {
property bool spaceDown: false
Item {
width: parent.width
height: frame.height
Frame {
id: frame
width: parent.width
opacity: holdArea.focus ? 0.2 : 1.0
TextEdit {
id: textEdit
width: parent.width
Keys.onPressed: {
if (event.key === Qt.Key_Space) {
if (spaceDown) {
holdArea.forceActiveFocus();
} else {
spaceDown = true;
}
}
}
}
}
Item {
id: holdArea
focus: true
Keys.onReleased: {
spaceDown = false;
textEdit.forceActiveFocus();
}
}
}
}
You can try the first part here

SwiftUI - I can not change the style of Picker's text on screen

I have a picker like this:
Picker(languages[currentIndex].name,selection: $currentIndex){
ForEach(0..<languages.count, id: \.self){index in
Text(languages[index].name)
}
}
And it looks like this:
I'm trying to style the blue 'English' text that you see on the screenshot. So far I've tried to give some styling to the Text, and the Picker itself but I could not succeed it.
The picker is meant to be in menu style, so I can not change the pickerStyle to another one (i.e. wheel). I explicitly mentioned it because when I make it like this, it works:
Picker(languages[currentIndex].name,selection: $currentIndex){
ForEach(0..<languages.count, id: \.self){index in
Text(languages[index].name)
.font(.custom("Montserrat Medium", size:16))
}
}.pickerStyle(.wheel)
However, this is not what I'm looking for. I only need to style this blue "English" text:
Thanks in advance.
As a workaround you can use Menu instead of Picker:
struct ContentView: View {
let languages = ["English", "German", "Spanish"]
#State private var currentIndex = 0
var body: some View {
Menu {
ForEach(0..<languages.count, id: \.self) { index in
Button {
currentIndex = index
} label: {
Text(languages[index])
}
}
} label: {
Text(languages[currentIndex])
.foregroundColor(.orange)
.bold()
}
}
}

Animate box expansion in the center of the screen (React Native Animated)

Its my first time animating with react native's animated library. Is it possible to animate in the center of the screen? If so, how can I do that?
This is my code below:
I basically had a 60x60 box on the top left corner of my screen to go down 1/2 the screen and over 1/2 the width. I want it to expand horizontally about 150 px across. The problem is that the box is not expanding in the center of the screen
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import {
View,
Animated,
Dimensions,
Easing
} from 'react-native';
const {width,height} = Dimensions.get('window')
export default class App extends Component {
constructor(){
super()
this.state = {
width: new Animated.Value(60),//Animated.Value/ValueXY used to hook up animation attributes, also for single values
height: new Animated.Value(60),
animateXY : new Animated.ValueXY({x:0,y:0})//for vectors
}
}
componentWillMount(){
//called when an instance of a component is being created and inserted into the DOM
Animated.sequence([
//function where we add the ending results
Animated.timing(
this.state.animateXY,
{
toValue: {x:0, y:height/2},
duration: 2000
}),
Animated.timing(
this.state.animateXY,
{
toValue: {x:width/2, y:height/2},
duration: 2000,
}),
Animated.timing(
this.state.width,
{
toValue: 150,
duration: 3000
}),
]).start()
}
render() {
return (
<View>
<Animated.View
style={
{
width: this.state.width,
height:this.state.height,
backgroundColor:"teal",
position:'absolute',
top: this.state.animateXY.y,
left: this.state.animateXY.x,
}
}
/>
</View>
);
}
}
Any advice will do! thank you!
Jemma
You are not updating the height. Maybe in your case you can use the width only since it’s a square

How to stop the display of the native context menu on ios when using the QML TextInput

I am using Qt5.7.1
In iOS long press on the QML TextInput displays the native context menu with Select/Select All/Paste items. How do i prevent this menu from showing, while allowing the TextInput to still be editable.
If i use Qt 5.6.2 the TextInput displays no such menu.
With the below code i am able to prevent the context menu from displaying in 5.7.1, however the cursor position always ends up at the end of the text.
import QtQuick 2.5
import QtQuick.Window 2.0
Rectangle
{
color: "yellow"
width: 100; height: 100
Rectangle {
color: "white"
width: 100; height: 50
anchors.centerIn: parent
TextInput{
id:tip
text:"test123"
anchors.fill: parent
onActiveFocusChanged: {
console.log("tip onActiveFocusChanged")
}
onCursorPositionChanged: {
console.log("onCursorPositionChanged:" + tip.cursorPosition )
}
MouseArea {
id:ma
anchors.fill: parent
propagateComposedEvents:true
onPressed: {
console.log("ma onPressed:" + tip.cursorPosition )
mouse.accepted = true
tip.focus = false;
}
onClicked: {
console.log("ma onClicked:" + tip.cursorPosition )
mouse.accepted = false
tip.forceActiveFocus();
}
onPressAndHold:{
console.log("ma onPressAndHold")
mouse.accepted = true
tip.focus = false;
}
}
}
}
}
I wonder if there is some better way i could do this and also have a fully editable TextInput.
I could stop the edit menu from displaying on ios with the hack below :\
import QtQuick 2.5
import QtQuick.Window 2.0
Rectangle
{
color: "yellow"
width: 100; height: 100
Rectangle {
color: "white"
width: 100; height: 50
anchors.centerIn: parent
TextInput{
id:tip
text:"test123"
anchors.fill: parent
MouseArea {
id:ma
anchors.fill: parent
propagateComposedEvents:true
onPressed: {
mouse.accepted = false
tip.focus = false
tip.focus = true
}
}
onSelectedTextChanged:tip.deselect()
}
}
}

Titanium: add an ActivityIndicator to listView?

http://docs.appcelerator.com/titanium/3.0/?mobile=/api/Titanium.UI.ActivityIndicator
Is it possible to and how would I add an ActivityIndicator to a listView listItem? Possibly via the listView template on selected items...
Thanks in advance!
Yes, it is possible, here's a snippet:
First start by defining list item templates:
// Some text row
var someTextTemplate = {
properties: {
accessoryType: Ti.UI.LIST_ACCESSORY_TYPE_NONE
},
childTemplates: [ // Add view subcomponents to the ListItem
{
// Display a Label
type: 'Ti.UI.Label',
bindId: 'someRowText',
properties: {
font: {fontSize: '14dp'}
}
}
]
};
//This is your loading template
var loadingTemplate = {
properties: {
accessoryType: Ti.UI.LIST_ACCESSORY_TYPE_NONE
},
childTemplates: [ //And here is where the activity indicator goes
{
// Display an activity indicator
type: 'Ti.UI.ActivityIndicator',
// If there is a 'loadingIndicator' dictionary in the ListDataItem,
// that data binds with this view subcomponent (useful for changing
// the loading message, for example)
bindId: 'loadingIndicator',
properties: {
// Set the indicator properties
font: { fontSize: '22dp'},
width: Titanium.UI.SIZE,
height: Titanium.UI.SIZE,
// If you don't set visible to true, the indicator will not show,
// because unlike other UI elements, it is hidden by default
visible: true,
//Other styles available, just check the component doc
style: Titanium.UI.iPhone.ActivityIndicatorStyle.PLAIN
}
}
]
};
Then setup your ListView
// Create the list section
var listSection = Titanium.UI.createListSection();
// Add the list section to a list view
var listView = Titanium.UI.createListView({
width: Ti.UI.FILL,
height: Ti.UI.SIZE,
layout: 'vertical',
touchEnabled: true,
sections: [listSection],
templates: {'rowText': someTextTemplate, 'loading': loadingTemplate },
defaultItemTemplate: 'rowText',
showVerticalScrollIndicator: true
});
Finally, add some list data items
var someData = [];
// This will add a row with a label, because we've set 'rowText' as our
// default ListView template
someData.push({
someRowText: { text: 'Some text row 1'}
});
// This will also show another label row, because we're specifying
// the template to use, in this case the label one
someData.push({
someRowText: { text: 'Some text row 2'},
template: 'rowText'
});
// Now we're going to use the 'loading' template, therefore showing
// the activity indicator in the row
someData.push({
loadingIndicator: { message: 'Please wait while transfering data from the mothership...' },
template: 'loading'
});
//Add our data items to the listview section
listSection.setItems(someData);
You can also mix multiple templates, but I've tried to simplify the example as much as possible.

Resources