【问题标题】:React-dnd not working in Cordova on iOSReact-dnd 在 iOS 上的 Cordova 中不起作用
【发布时间】:2016-11-21 12:32:57
【问题描述】:

我正在使用 react-dnd-touch-backend。

我能够让我的 DragSource 正确拖动,但 DropTargets 不接受它们(或对被拖动做出反应)。

应用程序只为每个角色使用一个包装器组件(DragSource 和 DropTarget)。我还定义了一个自定义拖动层。在添加自定义拖动层之前,拖放工作正常,除了我的 DragSources 在 iOS 上不可见(这就是我首先添加拖动层的原因),但现在我可以看到 DragSources,但 DropTargets 不起作用。

非常感谢任何帮助。

拖动源:

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)}}/>
    );
  }
}

放置目标:

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>
    );
  }
}

【问题讨论】:

    标签: javascript ios cordova reactjs drag-and-drop


    【解决方案1】:

    问题是 react-dnd-touch-backend 库中的这个问题: https://github.com/yahoo/react-dnd-touch-backend/issues/34

    回滚到版本 0.2.7 修复了该问题。

    【讨论】:

      猜你喜欢
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 2017-03-03
      • 1970-01-01
      • 2020-09-24
      相关资源
      最近更新 更多