uni.showLoading({
title: '海报生成中,请耐心有等待...',
mask: true,
});
let imgurl = await createCanvas(item);
//await createCanvas(item);
uni.hideLoading();
copyText(item.content)
// #ifdef MP-WEIXIN
uni.showShareImageMenu({
path: imgurl,
needShowEntrance: false,
});
// #endif
uni.getClipboardData({
success: (res) => {
console.log('剪贴板内容:', res.data);
},
fail: (err) => {
console.error('获取剪贴板内容失败:', err);
}
})
其中 // 复制文本
const copyText = (text) => {
const cleanText = convertToTextWithBreaks(text);
uni.setClipboardData({
data: cleanText,
success: (res) => {
console.log('复制成功:', res);
uni.showToast({
title: '复制成功',
icon: 'success',
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none',
});
},
});
};
现在控制台报
09:19:15.787 复制成功:, [Object] {"errMsg":"setClipboardData:ok"} at pages/jiaolian.vue:274
09:19:15.787 获取剪贴板内容失败:, [Object] {"errMsg":"getClipboardData:fail"} at pages/jiaolian.vue:631
这个问题只是在ios上出现,安卓正常,小程序和鸿蒙没有测试。
如果我不执行createCanvas这个方法,那剪切板的内容正常获取得到,只要一执行createCanvas方法, 不管copyText方法和绘制之前还是在绘制之后,都再也获取不到内容。
以下是careteCanvas方法的代码
const createCanvas = async (item) => {
if (!item.coverImage) return ''
// 1. 确保头像和二维码已加载
try {
if (!avatarPath.value || !qrcodePath.value) {
await initAvatarQrcode();
}
let imagePathUrl = null
let imgInfo = null
let imgWidth = null
let imgHeight = null
if (item.coverImage) {
imagePathUrl = await downloadFile(item.coverImage)
imgInfo = await getImageInfo(imagePathUrl);
imgWidth = screenWidth.value;
let ratioVal = screenWidth.value / imgInfo.width
screenHeight.value = imgInfo.height * ratioVal
imgHeight = screenHeight.value
await new Promise((resolve, reject) => {
nextTick(() => {
setTimeout(() => {
resolve()
}, 50)
})
})
}
const ctx = uni.createCanvasContext('posterCanvas', this);
// 清空并设置背景
ctx.clearRect(0, 0, imgWidth, imgHeight);
// ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, imgWidth, imgHeight);
// 绘制图片
ctx.drawImage(imagePathUrl, 0, 0, imgWidth, imgHeight);
// 二. 绘制用户信息区域(放在图片下方)
let bgXPos = 0
let bgYPos = imgHeight - (imgHeight / 5)
// 绘制圆形头像
const avatarY = bgYPos + 40
ctx.save()
ctx.beginPath()
ctx.arc(55, avatarY, 35, 0, 2 * Math.PI)
ctx.closePath()
ctx.clip()
ctx.drawImage(avatarPath.value, 20, avatarY - 35, 70, 70)
ctx.restore()
// 2.绘制二维码
let qrXPos = imgWidth - 130
let qrYPos = bgYPos
ctx.drawImage(qrcodePath.value, qrXPos + 30, qrYPos, 80, 80);
// 4.绘制用户信息
// 4.1绘制驾校名称
ctx.setFillStyle('#515151');
let textX = bgXPos + 100;
ctx.font = 'bold 18px sans-serif';
let text = jiaolian.value.nickname
if (text.length > 8) {
text = text.substring(0, 8) + '...'
}
ctx.fillText(text, textX, bgYPos + 30);
// 5.1绘制招生电话
ctx.font = 'nobold 14px sans-serif';
ctx.fillText(jiaolian.value.mobile, textX, bgYPos + 60);
// 执行绘制 - 使用回调确保绘制完成
ctx.draw();
return new Promise((resolve, reject) => {
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: 'posterCanvas',
width: imgWidth,
height: imgHeight,
destWidth: imgWidth * 3,
destHeight: imgHeight * 3,
success: (res) => {
resolve(res.tempFilePath);
},
fail: (err) => {
console.error('canvasToTempFilePath失败:', err);
reject(err);
}
}, this); // 注意这里的this指向
}, 100); // 稍微延迟确保绘制完成
});
} catch (err) {
console.error('海报生成异常:', err);
uni.showToast({
title: '海报生成失败',
icon: 'none',
});
throw err;
}
};
1 个回复
Ask小助手 - Ask社区AI助手
根据知识库中的信息,iOS 系统对剪贴板的访问有严格的权限和时机限制,特别是在涉及异步操作(如画布生成)后,
uni.getClipboardData可能会出现获取失败的情况。建议改用 Native.js 方式操作剪贴板,可以避免 iOS 平台的限制。插件市场提供了封装好的解决方案:
使用 操作系统粘贴板 插件(dc-clipboard),该插件基于 Native.js 实现,可设置/获取系统粘贴板中的文本内容,且不会弹出默认的 toast 提示。
使用方法:
common/dc-clipboard/clipboard.js调用方法:
注意事项:
uni.setClipboardData和uni.getClipboardData,使用 Native.js 方式可以避免 iOS 系统对剪贴板访问的异步限制uni.setClipboardData后立即调用uni.hideToast()另外,建议调整代码执行顺序,确保剪贴板操作尽可能在用户交互(如点击事件)的同步上下文中执行,避免在异步操作(如画布生成)之后再进行剪贴板读取操作。
要回复问题请先登录或注册
公告
更多>相关问题