The small program realizes the left sliding display button of a single card and prevents up and down sliding interference.

Posted by Warz on Fri, 11 Oct 2019 17:53:45 +0200

In order to realize the functions of the left sliding display, top setting and deleting buttons similar to the ios end wechat, we first need to set the button part as absolute positioning, and right as negative overflow screen. Using the api of event processing of small program, we can read the X/Y coordinates of the beginning of touch and the end of touch respectively, and change the position of the whole card according to the difference.

Here's a detail. In order to prevent button clicks from interfering with the sliding of the main part of the card, the whole card needs to be divided into two parts.

<View style={`${positionStyle[index]}`}>
    <View 
        onTouchStart={this.moveTaskStart}
        onTouchMove={this.moveTask}
        onTouchEnd={this.moveTaskEnd}
    >
        This is the main card section.
    </View>

    <View style= "right: -260px;">This is the button section that appears after sliding </View>.
</View>

The Taro framework is used here. The method, like the original event api, stores the X and Y coordinates at the beginning of sliding, calculates the distance of movement during finger movement, and expands the button when the distance of X is larger than that of the whole button section.

The realization of the core function only needs to analyze the X coordinates, but because the user may also shift the X coordinates during the sliding process, which will cause the button to expand, it is necessary to calculate the angle formed by the change of vertical coordinates and horizontal coordinates in both parts of move and end. When the angle is too large, it is regarded as sliding up and down, and the button does not expand.
The complete code is as follows:

moveTaskStart(e) {
    if (e.touches.length == 1) {
        //There is only one touch point on the touch screen.
        this.setState({
            // Start touching the X coordinates of the screen
            startX: e.touches[0].clientX,
            startY: e.touches[0].clientY
        });
    }
}

moveTask(e) {
    if (e.touches.length == 1) {
        let moveX = e.touches[0].clientX;
        let moveY = e.touches[0].clientY;
        // Moving distance
        let disX = this.state.startX - moveX;
        let disY = this.state.startY - moveY;
        let angle = disY > 0 ? disY / disX : -disY / disX;
        let btnWidth = this.state.btnWidth;
        let txtStyle = "";
        if (disX == 0 || disX < 30) {
            //Right slip
            txtStyle = "left:0px";
        } else if(angle > 0.5) {
            return;
        } else if (disX > 30 && angle < 0.5) {
            txtStyle = `left: -${disX}px`;
            if (disX >= btnWidth) {
                //Maximum distance
                txtStyle = `left: -${btnWidth}px`;
            }
        }
        let index = e.currentTarget.dataset.index;
        let list = this.state.positionStyle;
        this.setState({
            positionStyle: list
        });
    }
}

moveTaskEnd(e) {
    let txtStyle;
    if (e.changedTouches.length == 1) {
        let endX = e.changedTouches[0].clientX;
        let moveY = e.changedTouches[0].clientY;
        //Moving distance
        let disX = this.state.startX - endX;
        let disY = this.state.startY - moveY;
        //Moving angle
        let angle = disY > 0 ? disY / disX : -disY / disX;
        let btnWidth = this.state.btnWidth;
        //If the distance is greater than half the width of the button and the angle of movement is small, the button is displayed.
        if(disX > (btnWidth / 2) && angle < 0.5) {
            txtStyle = `left:-${btnWidth}px`
        }else {
            txtStyle = "left:0px"
        }
        let index = e.currentTarget.dataset.index;
        let list = this.state.positionStyle;
        list[index] = txtStyle;
        this.setState({
            positionStyle: list
        });
    }
}

Topics: iOS