私はreact-dnd-touch-backendを使用しています。iOSのCordovaでReact-dndが動作しません
DragSourcesを正しくドラッグできるようになりましたが、DropTargetsはそれらを受け入れません(またはドラッグして反応します)。
アプリケーションは、各ロール(DragSourceおよびDropTarget)に対して1つのラッパーコンポーネントのみを使用します。カスタムドラッグレイヤーも定義しました。 DragSourcesがiOS上で見えなくなったことを除けば、カスタムドラッグレイヤーを追加する前にドラッグ&ドロップが正常に機能しましたが(最初はドラッグレイヤーを追加した理由ですが)、DragSourcesが表示されますが、DropTargetsは機能しません。
ご迷惑をおかけして申し訳ありません。
たDragSource:
import React from "react";
import cn from "util/cn";
import {isCordova} from "util/detect-platform";
import {DragSource} from "react-dnd";
import {getEmptyImage} from "react-dnd-html5-backend";
require("./style.scss");
const TYPE = "DRAG-CONTAINER";
const source = {
beginDrag({value, left, top, children, DragPreviewComponent}) {
return {value, left, top, children, DragPreviewComponent};
}
};
function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
connectDragPreview: connect.dragPreview(),
isDragging: monitor.isDragging()
};
}
function getStyles(props) {
const {left, top, isDragging} = props;
const transform = `translate3d(${left}px, ${top}px, 0)`;
return {
transform: transform,
WebkitTransform: transform,
opacity: isDragging ? 0 : 1
};
}
@DragSource(TYPE, source, collect)
export default class DragContainer extends React.Component {
static propTypes = {
value: React.PropTypes.any
};
static defaultProps = {style: {}};
componentDidMount() {
if(!isCordova()) {
this.props.connectDragPreview(getEmptyImage(), {
captureDraggingState: true
});
}
}
render() {
const {className, isDragging, connectDragSource, style} = this.props;
const classNames = cn(
"Drag-container",
isDragging ? "Drag-container--dragging" : null,
className
);
return connectDragSource(
<div {...this.props} className={classNames} value={null} style={{...style, ...getStyles(this.props)}}/>
);
}
}
たDropTarget:
import React from "react";
import {DropTarget} from "react-dnd";
import cn from "util/cn";
require("./style.scss");
const TYPE = "DRAG-CONTAINER";
const target = {
drop(props, monitor) {
const {onDrop} = props;
const {value} = (monitor.getItem() || {value: null});
if(typeof onDrop === "function") {
setTimeout(() => onDrop(value), 100);
}
}
};
function collect(connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver()
};
}
@DropTarget(TYPE, target, collect)
export default class DropContainer extends React.Component {
static propTypes = {
onDrop: React.PropTypes.func
};
render() {
const {connectDropTarget, isOver, className} = this.props;
const classNames = cn("Drop-container", isOver ? "Drop-container--over" : null, className);
return connectDropTarget(
<div {...this.props} className={classNames} onDrop={null} onDragEnter={null} onDragExit={null}/>
);
}
}
カスタムドラッグ層:
import React from "react";
import {DragLayer} from "react-dnd";
const layerStyles = {
position: "fixed",
pointerEvents: "none",
width: "100%",
height: "100%",
zIndex: 100,
left: 0,
top: 0
};
function getItemStyles(props) {
const { initialOffset, currentOffset } = props;
if (!initialOffset || !currentOffset) {
return {
display: 'none'
};
}
let { x, y } = currentOffset;
if (props.snapToGrid) {
x -= initialOffset.x;
y -= initialOffset.y;
[x, y] = snapToGrid(x, y);
x += initialOffset.x;
y += initialOffset.y;
}
const transform = `translate(${x}px, ${y}px)`;
return {
transform: transform,
WebkitTransform: transform
};
}
@DragLayer(monitor => ({
item: monitor.getItem(),
itemType: monitor.getItemType(),
initialOffset: monitor.getInitialSourceClientOffset(),
currentOffset: monitor.getSourceClientOffset(),
isDragging: monitor.isDragging()
}))
export default class CustomDragLayer extends React.Component {
render() {
const {item, itemType, isDragging} = this.props;
if (!isDragging || !item) return null;
const {DragPreviewComponent} = item;
if(!DragPreviewComponent) return null;
return (
<div style={layerStyles}>
<div style={getItemStyles(this.props)}>
<DragPreviewComponent {...item}/>
</div>
</div>
);
}
}