I want to hide controls on mobile devices but there is only true or false values in component props <Carousel controls={true}>. Is there any way to do this with react-bootstrap? Or maybe is another simple way?
On mount of the component, you can check to see the device size. After that, assess if the Carousel controls need to be false (on small devices) or true (on big devices).
For example on functional components:
function App(){
const [controlsAreVisible, setControlsAreVisible] = useState(true);
useEffect(()=>{
// iPhone X width, for example
if (window.innerWidth <= 375) {
setControlsAreVisible(false)
}
// you can also set up event listeners here for "resize" for full responsiveness
}, [])
return(
<Carousel controls={controlsAreVisible}>
...
)
}
Related
I am implementing font size accessibility in a NativeScript-Vue app.
I want to allow or prevent Label resizing through an XML attribute for both Android and iOS, but behavior and implementation on the platforms are different.
Android
All labels are scaled by default. If I want a label not to resize, I need to call the function setTextSize in the loaded event, following this solution.
<Label text="Not resizable" #loaded="$androidFixedLabelSize($event, 70)" />
Vue.prototype.$androidFixedLabelSize = function({ object }, fontSize) {
if (object.android)
object.nativeView.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, utils.layout.toDevicePixels(fontSize));
}
iOS
Labels are not scaled by default. To resize a label, I need to use nativescript-accessibility-ext plugin and add the attribute accessibilityAdjustsFontSize.
<Label text="Resizable" accessibilityAdjustsFontSize="true" />
Having to add one attribute for fixed Android and one for resizable iOS is a bit cumbersome.
I was thinking of having all labels resizable by default, and specify if I want one not to resize through a directive or an attribute.
Can I achieve this through a custom directive? Or something else?
Update
I was able to prevent resizing on Android through a directive without hardcoding font size, but there is a problem: update is triggered only for few labels. el.nativeView.android in bind and inserted hooks is undefined.
Vue.directive("noresize", {
update: el => {
if (el.nativeView.android) {
el.nativeView.android.setTextSize(android.util.TypedValue.COMPLEX_UNIT_DIP, el.nativeView.fontSize);
} else {
// iOS code
}
}
});
On iOS, I would like to simply set accessibilityAdjustsFontSize="false", but this implies that it is true by default.
So the next question is: how do I set accessibilityAdjustsFontSize="true" on all Label components on iOS?
Thanks to Morten Sjøgren, developer of #nota/nativescript-accessibility-ext, I was able to add a global event. Accessibility resizing is now applied on all Label components, unless the attribute noResize is true.
app.js
import '#nota/nativescript-accessibility-ext';
import { Label } from 'tns-core-modules/ui/label';
// code
Label.on(Label.loadedEvent, ({ object }) => {
if (object.noResize) {
if (object.android) {
object.nativeView.setTextSize(android.util.TypedValue.COMPLEX_UNIT_DIP, object.fontSize);
}
} else {
object.accessibilityAdjustsFontSize = "true";
}
});
<Label text="Don't resize" noResize="true" />
I use a FlatList component for images grid because it have a good performance:
<FlatList
data={photos}
columnWrapperStyle={styles.listColumn}
numColumns={4}
renderItem={photo => this.renderPhoto(photo)}
/>
For now renderPhoto func return a new FastImage component (i use it because it have a cool caching feature)
<FastImage
resizeMode={FastImage.resizeMode.cover}
source={{uri: photo.src}}
/>
In the end I have something like this:
But now I want to have a very familiar possibility. Tap on the image will start the animation after which the image will be stretched to the full width of the screen.
After that, the user can do the following:
Swipe left/right to see prev/next images from the FlatList
Zoom current image
Tap on image to show/hide control elements (footer and header)
Swipe up/down for closing carousel and return to the grid component
It might look something like this:
So, whats a problem?
All existing carousel solutions are a wrapper for an image collection. But I cant pass wrapper component inside FlatList.
I could not find a ready-made component for solving such a common problem.
There are some that I try to combine (Lightbox, Carousel). But this solution will greatly affect performance. (I need to load the entire collection of images from the FlatList into the carousel component) In addition, such solutions usually have problems with animation.
So I'm wondering if there really is no react-native solution for such a popular image view mechanics?
Perhaps it is worth making a native module on the swift/objc (FlatList of images with carousel modal)?
Actually is possible with the elements that you have.
First you have the carousel (react-native-looped-carousel):
const activeProps = {
resizeMode: 'contain',
flex: 1,
width: null
};
const { height, width } = Dimensions.get('window');
const renderCarousel = (album, currentPage) => (
<Carousel style={{ width, height }} currentPage={currentPage} autoplay={false}>
{album.map(image => (
<FastImage
style={{ flex: 1 }}
resizeMode={FastImage.resizeMode.contain}
source={{ uri: image.uri }}
key={image.uri}
/>))
}
</Carousel>
);
Then FastImage (react-native-fast-image) with the lightbox (react-native-lightbox):
LightImage = (props) => {
const currentPage = this.items.findIndex(x => x.uri === props.source.uri);
return (
<Lightbox
activeProps={activeProps}
renderContent={() => renderCarousel(this.items, currentPage)}
>
<FastImage {...props} />
</Lightbox>
);
}
Now you can use your renderItem with the component for the FastImage and Lightbox
<FlatList
data={this.items}
columnWrapperStyle={styles.listColumn}
numColumns={4}
renderItem={photo => this.LightImage(photo)}
/>
I've copied part of my code, so it won't work with just copy and paste. If you have any question feel free to ask!
There's only one problem with this implementation that if you rotate the device the layout breaks
I'm trying to change the height of the progress component in nativescript like this:
<Progress value="{{ progress }}" maxValue="{{totalTime}}" height="100">
</Progress>
But the height property has no effect. How do I change the height of this component?
You can change the height of ProgressBar using the height property (due to some spcific in the native controls).
However one of the gret advantages of NativeScript is that you have direct access to the native APIs for both iOS and Android. So after some small research here is how I managed to change the default scale (there might be even better approaches - this is one of the shortest I came upon).
TypeScript example:
Use the laoded event to get the reference to your progress bar in the code behind.
<Progress minValue="0" maxValue="100" value="25" loaded="onProgressLoaded"/>
Then in the code behind access the native controls
import { Progress } from 'ui/progress';
import { isAndroid, isIOS } from "platform"
declare let CGAffineTransformMakeScale: any; // or use tns-platform-declarations instead of casting to any
export function onProgressLoaded(args: EventData) {
let progress = <Progress>args.object;
if (isAndroid) {
progress.android.setScaleY(5); // progress.android === android.widget.ProgressBar
} else if (isIOS) {
let transform = CGAffineTransformMakeScale(1.0, 5.0);
progress.ios.transform = transform; // progress.ios === UIProgressView
}
}
Full demo app can be found here
You can directly set scaleY attribute of the progress element.
Example:
<Progress scaleY="2" value="{{ progress }}" maxValue="{{totalTime}}" height="100"></Progress>
This will make it 2 times wider in the vertical (Y) axis.
On mobile devices, OpenLayers 3 - full screen icon, in case of Mozilla Firefox doesn't show.
Is there a way to solve this or set an icon myself to show on every device?
Thanks,
Eylul
You can easily set your own icon using the label and labelActive constructor options of ol.control.FullScreen.
$('.ol-full-screen-false').attr('title', 'Visualizza a schermo intero');
$('.ol-full-screen-false').html('<img src="icons/fullscreen_s.png"/>');
if (document.addEventListener)
{
document.addEventListener('webkitfullscreenchange', fullscreenHandler, false);
document.addEventListener('mozfullscreenchange', fullscreenHandler, false);
document.addEventListener('fullscreenchange', fullscreenHandler, false);
document.addEventListener('MSFullscreenChange', fullscreenHandler, false);
}
function fullscreenHandler()
{
if (document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement !== null)
{
$('.ol-full-screen-true').attr('title', 'Chiudi la visualizzione a schermo intero');
$('.ol-full-screen-true').html('<img src="icons/close_s.png"/>');
$('.ol-full-screen-false').attr('title', 'Visualizza a schermo intero');
$('.ol-full-screen-false').html('<img src="icons/fullscreen_s.png"/>');
}
}
Solution with Fontawesome expand icon:
var fspan = document.createElement('i');
fspan.setAttribute('class', 'fa fa-expand');
...
// use it in map control definition
new ol.control.FullScreen({ label: fspan, tipLabel: 'Fullscreen' })
developing for Gear s2 web app (Tizen),
how is it possible to scroll a page which has only text, using the bezel?
Thanks.
First you have to listen to the "rotarydetent" events, e.g. like following:
document.addEventListener('rotarydetent', onRotarydetent);
function onRotarydetent(ev) {
var direction = ev.detail.direction;
if(direction === "CW"){ // CW = clockwise; CCW = counterclockwise
... scroll down ...
} else {
... scrull up ...
}
}
So now to scroll the page content it depends on how build your web app. If you use the SDK Wizard and have a project including tau.js it will be simple if you know that tau adds a scroller container around each page. Now you just need to find the scroller and scroll it. Using jQuery it could look like following:
function onRotarydetent(ev) {
var direction = ev.detail.direction,
uiScroller = $('#pageid').find('.ui-scroller'),
scrollPos = $(uiScroller).scrollTop();
console.debug("onRotarydetent: " + direction);
if(direction === "CW"){
$(uiScroller).scrollTop(scrollPos + 100); // scroll down 100px
} else {
$(uiScroller).scrollTop(scrollPos - 100); // scroll up 100px
}
}
Have a look at the UIComponents sample app available within the Tizen Wearable SDK.
You need to use the TAU library to achieve Text scrolling using Beezel.
Create a new project using the UI Components app and Install it on Gear s2 emulator or original hardware. Then Run the app and click on the first option 'Header' which contains your use case i.e. plain text scrollable by beezel.